一尘不染

使用Entity Framework手动输入密钥

c#

我试图首先将Entity Framework代码用于一个简单的数据库项目,但遇到一个我根本无法解决的问题。

我注意到EF设置的表ID每次自动增加1,完全忽略了我为该字段手动输入的值。经过一番搜索,据我了解,禁用此行为的正确方法是在做:

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

但是现在我只收到此错误,我不知道为什么:

未处理的异常: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; }
}

提前致谢。


阅读 260

收藏
2020-05-19

共1个答案

一尘不染

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

如果查看创建表的迁移,应该会看到以下内容:

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

然后,您使用Fluent API将模型更改为DatabaseGenerated.None。EF将其纳入迁移过程:

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

和生成的SQL是这样的:

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

实际上确实确实蹲下了。从列中删除IDENTITY并非易事。您需要删除并重新创建表或创建新列,然后必须复制数据并修复外键。因此,EF并未为您做到这一点也就不足为奇了。

您需要确定如何最好地自己做。现在,您可以将迁移回滚到0并从头开始重新设置支架DatabaseGeneratedOption.None,或者可以手动更改迁移以删除并重新创建表。

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

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

编辑, 或者您可以使用自定义迁移操作打开/关闭身份

2020-05-19