使用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; }