我有两个看起来像这样的实体类:
public class VendorLocation
{
//Primary Key
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public Vendor Vendor { get; set; }
//Location address
public string Address { get; set; }
}
public class Vendor
{
//Primary Key
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
//List of locations for this vendor
public List<VendorLocation> Locations { get; set; }
}
正如您所看到的,存在一对多关系,供应商可以拥有多个位置。我有一个网络表单,其中包含单个Vendor
的位置列表。当用户提交页面时,它会将整个位置列表提交给Controller
。 Controller执行一些逻辑以将ViewModel映射到VendorLocation
的列表。然后,我的服务层负责同步供应商的更新位置列表:
public async Task<Entities.Vendor> SetVendorLocationsAsync(Entities.Vendor vendor, List<Entities.VendorLocation> locations)
{
//Input locations should already have an ID if they are existing in the DB, so we can simple sync the whole list here
vendor.Locations = locations;
await _repository.UpdateAsync(vendor);
return vendor;
}
UpdateAsync
代码如下所示:
/**
* Save an updated model to persistence
*/
public async Task UpdateAsync(TEntity model)
{
_context.Update(model);
await _context.SaveChangesAsync();
}
在上面的代码中,如果用户更新了位置,则每个VendorLocation
都会将Id
设置为数据库中的现有Id
。任何新位置的Id
都为零。
根据文档(EF Core - Disconnected Entities),它说明如下:
使用自动生成的密钥,Update可以再次用于两个插入 并且更新,即使图表包含需要的实体组合 插入和需要更新的那些。
但是,我收到了例外情况:
MySqlException: Duplicate entry '3' for key 'PRIMARY'
上述文件具体说明:
更新将标记图表,博客或帖子中的任何实体,以便插入 如果它没有设置键值,而所有其他实体都是 标记为更新。
我会假设,因为我的对象已经有一个Id
集,EF Core会将其标记为更新。为什么要再次插入?我在这里误解了什么吗?