【发布时间】:2018-11-19 10:52:44
【问题描述】:
考虑
public class Item
{
public int Id{get;set;}
public string Name{get;set;}
public List<ItemTag> ItemTags{get;set;}
}
public class ItemTag
{
public int Id{get;set;}
public int Name{get;set;}
}
我现在使用实体框架核心将 ItemTag 添加到 Item。这工作得很好。
现在我向同一个项目添加第二个 ItemTag。保存时,传递整个对象,包括现有的相关ItemTags。然后,EF 尝试插入现有的 ItemTag,但失败并出现“无法将值插入标识列...”的异常。
那么如何防止现有对象被插入?
我的解决方法是遍历 ItemTags,并将任何具有 Id 的内容设置为 EntityState.Unchanged 以强制它不保存它。但似乎不需要这样的解决方法。
这是保存项目的代码:
//Get the current item, so that only updated fields are saved to the database.
var item = await this.DbContext.Items.SingleAsync(a => a.Id == itemInput.Id);
item.UpdatedBy = this._applicationUserProvider.CurrentAppUserId;
item.Updated = DateTimeOffset.UtcNow;
//Use Automapper to map fields.
this._mapper.Map(itemInput, item);
//Workaround for issue.
foreach (var itemTag in item.ItemTags)
{
var entry = this.DbContext.Entry(itemTag);
if (itemTag.Id > 0)
{
entry.State = EntityState.Unchanged;
}
}
await this.SaveChangesAsync();
【问题讨论】:
-
简单修复:不要使用 AutoMapper。 AutoMapper 的作者多次表示它不适合这种映射。只有持久性模型 -> DTO 或 ViewModel 和/或域模型 -> ViewModel/DTO。永远不要反过来。 EF Core 通过引用跟踪实体,自动映射器创建新引用,因此问题
-
@Tseng,好的。我对此一无所知。所以我应该手动编写从输入到实际的映射?
-
没有。 AM.Collection 可以为您添加对 AM 的支持。
-
@LucianBargaoanu,你能解释一下吗?也许是一个例子?
-
@LucianBargaoanu,似乎还不支持 EF Core:github.com/AutoMapper/AutoMapper.Collection.EFCore
标签: asp.net-core entity-framework-core asp.net-core-2.1 entity-framework-core-2.1