0

对于以下课程:

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,并且应该只在 C 点分配一个 ID。但是,我发现对于我的一个类,在 B 点分配了一个 ID,这导致抛出此异常:

当 IDENTITY_INSERT 设置为 OFF 时,无法在表“Cars”中插入标识列的显式值。

我玩过 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 应用了一些实际上不在数据库中的 relashionships。

我重置了整个迁移(删除了迁移文件夹和 _migrationhistory 表,然后在 PowerShell 中执行了 Enable-Migrations 和 Add-Migration Init),并且我已经能够在初始迁移文件中看到有问题的行。

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

4

2 回答 2

0

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

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);
// ....
}
于 2015-02-20T11:15:53.057 回答
-1

您可以将 Id 列归因于

public Car 
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Brand {get; set; }
}
于 2015-02-20T11:18:58.023 回答