我有一个带有属性Id(类型为int)的抽象基础对象。我有" DatabaseGeneratedOption.Identity"选项。 (这可以在下面看到)。
有两个派生实体,节点和标签。它们都没有Id属性,因为它们被假定从基类继承它。 (也见下面的代码)。
当使用相同的DbContext实例时,我可以添加任意数量的节点,然后保存更改。但是,只要我添加一个Tag(并且只在我添加了节点之后),就抛出异常。当我做相反的事情时也是如此。我可以添加任意数量的标签,然后保存更改,但只要我添加一些节点并尝试保存更改,就会抛出异常。
例外:
System.InvalidOperationException:对数据库的更改是 已成功提交,但更新时发生错误 对象上下文。 ObjectContext可能处于不一致状态。 内部异常消息:保存或接受更改失败,因为 不止一个实体类型' Entities.Node'拥有相同的主键 值。确保显式设置的主键值是唯一的。 确保正确配置数据库生成的主键 在数据库和实体框架模型中。使用实体 Database First / Model First配置的Designer。使用 ' HasDatabaseGeneratedOption"流利的API或 ' DatabaseGeneratedAttribute'用于Code First配置。 ---> System.InvalidOperationException:保存或接受更改失败 因为不止一个实体类型为'Entities.Node'有同样的 主键值。确保显式设置主键值 独特。确保已配置数据库生成的主键 正确地在数据库和实体框架模型中。使用 数据库优先/模型优先配置的实体设计器。使用 ' HasDatabaseGeneratedOption"流利的API或 ' DatabaseGeneratedAttribute'用于Code First配置。
DbContext定义:
// Node Entity
modelBuilder.Entity<Node>().HasRequired(t => t.NodeTypeEntity).
WithMany(t => t.Nodes).HasForeignKey(t => t.NodeTypeId);
modelBuilder.Entity<Node>().HasOptional(t => t.Parent).
WithMany(t => t.Children).HasForeignKey(t => t.ParentId);
modelBuilder.Entity<Node>().HasMany(t => t.Children).
WithOptional(t => t.Parent);
modelBuilder.Entity<Node>().HasMany(t => t.Tags).WithMany(t => t.Nodes);
modelBuilder.Entity<Node>().Property(t => t.Location).IsOptional().HasMaxLength(100);
modelBuilder.Entity<Node>().Ignore(t => t.SourceDefinitions);
modelBuilder.Entity<Node>().Ignore(t => t.NodeType);
// Tags Entity
modelBuilder.Entity<NWatchTag>().Property(t => t.TagDesc).
IsOptional().HasMaxLength(500);
modelBuilder.Entity<NWatchTag>().Property(t => t.IsSystem).IsOptional();
modelBuilder.Entity<NWatchTag>().HasMany(t => t.Nodes).WithMany(t => t.Tags);
// Base Entity
modelBuilder.Entity<BaseEntityObject>().HasKey(t => t.Id);
modelBuilder.Entity<BaseEntityObject>().Property(t => t.Id).
HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<BaseEntityObject>().Property(t => t.NativeId).IsRequired();
modelBuilder.Entity<BaseEntityObject>().Property(t => t.Name).
IsRequired().HasMaxLength(100);
modelBuilder.Entity<BaseEntityObject>().Property(t => t.DisplayName).
IsOptional().HasMaxLength(100);
modelBuilder.Entity<BaseEntityObject>().Property(t => t.Alias).
IsOptional().HasMaxLength(100);
modelBuilder.Entity<BaseEntityObject>().Property(t => t.SourceId).IsRequired();
modelBuilder.Entity<BaseEntityObject>().Property(t => t.AccessLevel).IsRequired();
modelBuilder.Entity<BaseEntityObject>().Property(t => t.CreatedOn).IsRequired();
modelBuilder.Entity<BaseEntityObject>().Property(t => t.CreatedBy).
IsRequired().HasMaxLength(50);
modelBuilder.Entity<BaseEntityObject>().Property(t => t.ModifiedOn).IsOptional();
modelBuilder.Entity<BaseEntityObject>().Property(t => t.ModifiedBy).
IsOptional().HasMaxLength(50);
public override int SaveChanges()
{
var changeSet = ChangeTracker.Entries<BaseEntityObject>();
foreach (var entity in changeSet)
{
switch (entity.State)
{
case EntityState.Added:
entity.Entity.CreatedOn = DateTime.UtcNow;
if (String.IsNullOrEmpty(entity.Entity.CreatedBy))
{
entity.Entity.CreatedBy = "System";
}
break;
case EntityState.Modified:
entity.Entity.ModifiedOn = DateTime.UtcNow;
if (String.IsNullOrEmpty(entity.Entity.ModifiedBy))
{
entity.Entity.ModifiedBy = "System";
}
break;
}
}
return base.SaveChanges();
}
使用DbContext进行编程:
var testTag = new Tag("TestTag");
dbContext.Tags.Add(testTag);
dbContext.SaveChanges();
dbContext.Nodes.Add(new Node(1, "node1", testType, Source.CasApi));
dbContext.SaveChanges(); <=== EXCEPTION THROWN HERE