使用Entity Framework手动input密钥

我试图首先使用实体​​框架代码为一个简单的数据库项目,我遇到了一个问题,我根本无法弄清楚。

我发现EF设置我的表的ID自动增加1,完全忽略我手动input该字段的值。 经过一番search,我的理解是禁用这种行为的正确方法是:

modelBuilder.Entity<Event>().Property(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 

但是现在我只是得到这个错误,我不知道为什么:

未处理的exception:System.Data.Entity.Infrastructure.DbUpdateException:更新条目时发生错误。 详情请参阅内部例外。 —

System.Data.UpdateException:更新条目时发生错误。 详情请参阅内部例外。 —> System.Data.SqlClient.SqlException:当IDENTITY_INSERT设置为OFF时,无法在表“事件”中为标识列插入显式值。

如果有帮助的话,这里是POCO课程:

 public class Event { [Key, Required] public int EventID { get; set; } public string EventType { get; set; } //TODO: Event Type Table later on public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public virtual ICollection<Match> Matches { get; set; } public virtual ICollection<EventParticipation> EventParticipation { get; set; } } 

提前致谢。

默认情况下,Entity Framework假定整数主键是数据库生成的(相当于在Fluent API中添加属性HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)或调用Property(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

如果你看看创build表的迁移,你应该看到这个:

  CreateTable( "dbo.Events", c => new { EventID = c.Int(nullable: false, identity: true), //etc }) .PrimaryKey(t => t.EventID ); 

然后,您使用Fluent API将模型更改为DatabaseGenerated.None 。 英孚在迁移中提到:

 AlterColumn("dbo.Events", "EventID", c => c.Int(nullable: false, identity: false)) 

而生成的SQL是这样的:

ALTER TABLE [dbo].[Events] ALTER COLUMN [EventID] [int] NOT NULL

其实确实蹲下了。 从列中删除IDENTITY不是微不足道的。 您需要删除并重新创build表或创build一个新列,然后您必须复制数据并修复外键。 所以英孚不会为你做这件事就不足为奇了。

你需要弄清楚如何最好的为自己做。 您可以将您的迁移回滚到0,并重新从头开始重新脚手架,而您已经指定了DatabaseGeneratedOption.None ,或者可以手动更改迁移以删除并重新创build表。

或者您可以删除并重新创build列:

 DropColumn("Customer", "CustomerId"); AddColumn("Customer", "CustomerId", c => c.Long(nullable: false, identity: false)); 

编辑或者你可以通过自定义迁移操作来打开/closures标识

因为我更喜欢属性,所以在这里为了完整性而select:

 [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int Id { get; set; }