Dbset <tentity> .Add(entity)分配一个ID,这会导致异常</tentity>

时间:2015-02-20 11:06:22

标签: c# entity-framework entity-framework-6 dbset

以下课程:

public Car 
{
    public int ID { get; set; }
    public string Brand {get; set; }
}

通常我们这样做:

Car c = new Car { Brand = "Jaguar" } ; // Point A
context.Cars.Add(c); // Point B
context.SaveChanges() // Point C

在B点,ID应该保持为0,并且ID只应该在C点分配。但是,我发现对于我的一个类,在B点分配了一个ID,这导致了这个例外。抛出:

  

无法在表中插入identity列的显式值   &#39;汽车&#39;当IDENTITY_INSERT设置为OFF时。

我玩了Fluent API,我99%确定我的关系是正确定义的。我无法弄清楚为什么这个DbSet试图为这个实体分配一个ID。

更新

感谢您的帮助,所以这里有一个更详细的说明我的情况:

public Car 
{
    public int ID { get; set; }
    public string Brand {get; set; }
    public int Driver1ID {get; set;}
    public Person Driver1 {get; set;}
    public int Driver2ID {get; set;}
    public Person Driver2 {get; set;}
}

public Person
{
   public int ID { get; set; }
   public string Name { get; set; }
}

这是我的流利配置:

modelBuilder.Entity<Car>().HasKey(x => x.ID);
            modelBuilder.Entity<Car>().Property(x => x.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); // Added following Igor's suggestion
            modelBuilder.Entity<Car>().HasRequired(x => x.Driver1).WithOptional().WillCascadeOnDelete(false);
            modelBuilder.Entity<Car>().HasRequired(x => x.Driver2).WithOptional().WillCascadeOnDelete(false);

修改2

好吧,我发现实际上迁移搞砸了。由于某种原因,EF将第二个外键(Driver2)放在主键列上。这就是为什么DbSet.Add()使用实际上是Driver 2 ID的值填充ID列。

我真的不知道EF为什么会这样混淆。奇怪的是,当我查看SQL Management Studio时,我没有看到这个FK。看起来EF应用了一些实际上不在数据库中的关系。

我重置了整个迁移(删除了迁移文件夹和_migrationhistory表,然后在PowerShell中执行了启用迁移和添加迁移初始化),我已经能够在初始迁移文件中看到有问题的行。

或者我当然修改过它们似乎解决了这个问题。

2 个答案:

答案 0 :(得分:0)

在您的流畅(也可以是声明)映射中,您可以指定数据库是使用Identity分配ID还是不分配ID。如果您指定它已分配,则您的代码也不应该分配它,因为您将获得异常。流利的你可以这样做:

public Car 
{
    public int ID { get; set; }
    public string Brand {get; set; }
    public int Driver1ID {get; set;}
    public Person Driver1 {get; set;}
    public int Driver2ID {get; set;}
    public Person Driver2 {get; set;}
}

public Person
{
   public int ID { get; set; }
   public string Name { get; set; }
}


protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
// ....
modelBuilder.Entity<Car>().HasKey(x => x.ID);
modelBuilder.Entity<Car>().Property(x => x.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); // set it on
modelBuilder.Entity<Car>().HasRequired(x => x.Driver1).WithMany().HasForeignKey(x => x.Driver1ID).WillCascadeOnDelete(false);
modelBuilder.Entity<Car>().HasRequired(x => x.Driver2).WithMany().HasForeignKey(x => x.Driver2ID).WillCascadeOnDelete(false);
// ....
}

答案 1 :(得分:-1)

您可以使用

对Id列进行归属
public Car 
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Brand {get; set; }
}