Entity framework core 实体框架核心导航未更新
为此,我使用EntityFramework核心v5.0.3 我正在为用户制作一个简单的信息应用程序,每个用户都可以拥有自己喜欢的颜色 人物模型Entity framework core 实体框架核心导航未更新,entity-framework-core,Entity Framework Core,为此,我使用EntityFramework核心v5.0.3 我正在为用户制作一个简单的信息应用程序,每个用户都可以拥有自己喜欢的颜色 人物模型 public class Person { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int PersonId { get; set; } [MaxLength(50)] public string FirstName {
public class Person
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PersonId { get; set; }
[MaxLength(50)]
public string FirstName { get; set; }
[MaxLength(50)]
public string LastName { get; set; }
public bool IsAuthorised { get; set; }
public bool IsValid { get; set; }
public bool IsEnabled { get; set; }
public virtual ICollection<FavouriteColour> FavouriteColours { get; set; }
}
彩色模型
public class FavouriteColour
{
[Key]
public int PersonId { get; set; }
public virtual Person Person { get; set; }
[Key]
public int ColourId { get; set; }
public virtual Colour Colour { get; set; }
}
public class Colour
{
[Key]
public int ColourId { get; set; }
public string Name { get; set; }
public bool IsEnabled { get; set; }
public virtual IList<FavouriteColour> FavouriteColours { get; set; }
}
执行wait后_context.SaveChangesAsync()代码>所有颜色都不会改变。我以为所有这些型号的目的都是为了让颜色自动改变
我设置了一个FavoriteColowerRepository
,而不是像这样进行更新
public async Task<bool> Update(int personId, ICollection<FavouriteColour> favouriteColours)
{
// empty their favourite colours
_context.FavouriteColours.RemoveRange(_context.FavouriteColours.Where(fc => fc.PersonId == personId);
// add new favourite colours
_context.FavouriteColours.AddRange(favouriteColours);
return true;
}
实际上更改了FavoriteColors参数,并强制进入最后一个状态,从而创建重复的主键,插入失败
那么,为什么新的最喜欢的颜色从未被插入,为什么在我试图清除用户已经拥有的所有颜色时,我的favoriteColors
参数被编辑
为什么最受欢迎的新颜色从未被插入
调用\u context.Update(person)代码>将个人
实体和所有相关的收藏夹颜色
实体置于修改
状态。因此,在下一个SaveChanges
调用中,EF应该向数据库提交更新命令
如果修改个人
实体的任何属性,您将发现该个人已正确更新。favoriteColour
实体的问题在于它只包含主键属性,而EF不修改键属性(或作为复合主键一部分的任何属性)。您可以使用以下代码对此进行测试-
var fc=dbCtx.favoriteColor
.FirstOrDefault(p=>p.PersonId==1和&p.colorID==4);
fc.colorId=6;//CoulourId是主键的一部分
dbCtx.SaveChanges();
你会遇到一个例外-
属性“FavoriteColour.colorId”是键的一部分,因此不能
被修改或标记为已修改
因此,EF甚至不会为收藏夹颜色
生成任何更新命令,即使所有颜色都标记为已修改
要更新人物
及其所有收藏夹颜色
,您需要执行以下操作-
//获取现有人员及其所有喜爱的颜色
var existingPerson=dbCtx.Persons
.包括(p=>p.FavoriteColor)
.FirstOrDefault(p=>p.Id==Id);
//如果需要,请修改Person的任何属性
//替换现有的收藏夹颜色列表
existingPerson.FavoriteColors=person.FavoriteColors;
//保存更改
dbCtx.SaveChanges();
这将-
删除现有列表中但不在新列表中的任何FavoriteColour
插入新列表中但不在现有列表中的任何FavoriteColour
有了存储库,如何实现这一点就取决于您了
为什么在尝试编辑时会编辑我的FavoriteColors参数
清除用户已有的所有颜色
在此操作之前,您调用了\u context.Update(person)代码>。因此,Person
现在作为现有实体在Modified
状态下被跟踪。那么当你打电话的时候-
\u context.favoriteColors.RemoveRange(\u context.favoriteColors.Where(fc=>fc.PersonId==PersonId));
\u context.favoriteColors.Where(fc=>fc.PersonId==PersonId)
部分从数据库中获取该人物的现有FavoriteColors
。因此,这些获取的favoriteColors
被添加到此人的favoriteColors
列表中(因为它正在被跟踪)
例如,假设您在控制器中收到一个带有4个FavoriteColour的Person
实体,数据库中有3个FavoriteColour
。调用\u context.Update(person)后代码>,将使用4个收藏夹颜色的列表跟踪此人。然后,当您从数据库中获取此人现有的FavoriteColors
时,将使用总共7个FavoriteColour
的列表跟踪此人
我希望这能遮住任何光线
public async Task<IActionResult> PutPerson(int id, Person person)
{
peopleRepository.Update(person);
}
public void Update(Person person)
{
_context.Update(person);
}
public async Task<bool> Update(int personId, ICollection<FavouriteColour> favouriteColours)
{
// empty their favourite colours
_context.FavouriteColours.RemoveRange(_context.FavouriteColours.Where(fc => fc.PersonId == personId);
// add new favourite colours
_context.FavouriteColours.AddRange(favouriteColours);
return true;
}
public async Task<IActionResult> PutPerson(int id, Person person)
{
peopleRepository.Update(person);
bool valid = await favouriteColourRepository.Update(id, person.FavouriteColours);
}
_context.FavouriteColours.RemoveRange(_context.FavouriteColours.Where(fc => fc.PersonId == personId);