如何在Entity Framework代码中手动设置实体主键第一个数据库?

好吧,我有以下模型结构:我有一个类 – 基本上是DatabaseEntity

 public class DatabaseEntity { public int Id { get; set; } } 

所以像产品,类别等每个实体都将inheritanceDatabaseEntity并拥有Id属性。 我还有使用InsertOrUpdate方法的典型EntityFramework存储库类:

 private readonly DbContext _database; public void InsertOrUpdate(TObject entity) where TObject : DatabaseEntity { if(entity.Id == default(int)) { // New entity DbSet().Add(entity); } else { // Existing entity _database.Entry(entity).State = EntityState.Modified; } _database.SaveChanges(); } 

然后我从eBay下载eBay api列表中的categoies我必须添加到数据库中。 基本上类别是:

 public class EbayCategory : DatabaseEntity { // It has Id since it inherits DatabaseEntity public string Name { get; set; } // ... some other properties } 

但问题是,当我下载这些类别时,我下载了他们的Id属性,当然,这些属性已经有了价值。 当我尝试将它们保存到数据库时:

 public void UpdateCategories(IEnumerable newCategories) { foreach (var newCategory in newCategories) { _repository.InsertOrUpdate(newCategory); } } 

我面临一些问题……首先, entity.Id != default(int)因为它有值,所以存储库尝试更新这个实体,而不是添加,但它不在数据库或上下文中,因此它会抛出以下例外:

 System.Data.Entity.Infrastructure.DbUpdateConcurencyException "Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries." 

…因为它认为其他人删除了我想要更新的实体。 如何保存此InsertOrUpdate逻辑,因为许多项目都基于它,并且能够将具有主键( Id )的项目( EbayCategories )添加到数据库,然后像其他实体一样更新/删除它们而不丢弃EbayCategory.Id值?

要允许您手动生成ID,您需要一个具有手动生成ID的类 – 因此它不能从DatabaseEntityinheritance

 public class EbayCategory { [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; } public string Name { get; set; } // ... some other properties } 

现在,您将需要一个不同的InsertOrUpdate来处理具有手动生成密钥的实体:

 public void InsertOrUpdate(EbayCategory entity) { if(Find(entity.ID == null) { // New entity DbSet().Add(entity); } else { // Existing entity _database.Entry(entity).State = EntityState.Modified; } _database.SaveChanges(); } 

Colin上面的答案非常正确地说明了如何使用数据注释来实现此设置。 但是在提出的问题中,实体是一个子类,因此您无法在不更改实体类的情况下添加注释。

还有一种替代配置方法:Fluent配置。 这是我使用EntityTypeConfiguration类的示例:

 public class LookupSchoolsConfiguration : EntityTypeConfiguration { public LookupSchoolsConfiguration() { Property(l => l.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); } } 

您还可以根据以下post将配置直接添加到modelBuilder: https ://stackoverflow.com/a/4999894/486028