在实体框架核心 2.0 中,我在Post和之间有很多关系Category(绑定类是PostCategory)。
当用户更新 a 时Post,整个Post对象(及其PostCategory集合)被发送到服务器,在这里我想重新分配新收到的集合PostCategory(用户可以通过添加新类别和删除一些类别来显着更改此集合)。
我用来更新该集合的简化代码(我只是分配了全新的集合):
var post = await dbContext.Posts
.Include(p => p.PostCategories)
.ThenInclude(pc => pc.Category)
.SingleOrDefaultAsync(someId);
post.PostCategories = ... Some new collection...; // <<<
dbContext.Posts.Update(post);
await dbContext.SaveChangesAsync();
Run Code Online (Sandbox Code Playgroud)
这个新集合的对象与先前集合中的对象 ID 相同(例如,用户删除了一些(但不是全部)类别)。由于,我得到一个例外:
System.InvalidOperationException:无法跟踪实体类型“PostCategory”的实例,因为已跟踪具有相同 {'CategoryId', 'PostId'} 键值的另一个实例。
如何有效地重建新集合(或简单地分配一个新集合)而不会出现此异常?
此链接中的答案似乎与我想要的有关,但它是一种很好且有效的方法吗?有没有可能更好的方法?
我得到我的帖子(编辑覆盖它的值)是这样的:
public async Task<Post> GetPostAsync(Guid postId)
{
return await dbContext.Posts
.Include(p => p.Writer)
.ThenInclude(u => u.Profile)
.Include(p => p.Comments)
.Include(p => p.PostCategories) …Run Code Online (Sandbox Code Playgroud) 说我有一Sale堂课:
public class Sale : BaseEntity //BaseEntity only has an Id
{
public ICollection<Item> Items { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和一Item类:
public class Item : BaseEntity //BaseEntity only has an Id
{
public int SaleId { get; set; }
public Sale Sale { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
以及通用存储库(更新方法):
public async Task<int> UpdateAsync<T>(T entity, params Expression<Func<T, object>>[] navigations) where T : BaseEntity
{
var dbEntity = _dbContext.Set<T>().Find(entity.Id);
var dbEntry = _dbContext.Entry(dbEntity);
dbEntry.CurrentValues.SetValues(entity);
foreach (var property in navigations) …Run Code Online (Sandbox Code Playgroud)