以下课程:
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列的显式值 '汽车'当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中执行了启用迁移和添加迁移初始化),我已经能够在初始迁移文件中看到有问题的行。
或者我当然修改过它们似乎解决了这个问题。
答案 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; }
}