asp.net 使用实体框架手动输入键

7tofc5zh  于 2023-05-23  发布在  .NET
关注(0)|答案(2)|浏览(226)

我试图使用实体框架代码首先为一个简单的数据库项目,我遇到了一个问题,我根本无法弄清楚。
我注意到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时,无法在表“Events”中插入标识列的显式值。
如果有帮助的话,下面是有问题的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; }
}

先谢谢你了。

ss2ws0br

ss2ws0br1#

因为我更喜欢attributes,所以为了完整起见,这里有一个替代方案:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

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

注意:这也适用于EF Core。

kmbjn2e3

kmbjn2e32#

默认情况下,Entity Framework假设整数主键是数据库生成的(相当于添加属性HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)或在Fluent API中调用Property(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);)。
如果您查看创建表的迁移,您应该看到以下内容:

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
它实际上并没有蹲下。Dropping the IDENTITY从一个列不是平凡的。您需要删除并重新创建表或创建一个新列,然后必须复制数据并修复外键。所以EF不为你做这些也就不足为奇了。
你需要弄清楚如何最好地为自己做这件事。既然指定了DatabaseGeneratedOption.None,您可以将迁移回滚到0并从头开始重新搭建,或者您可以手动更改迁移以删除并重新创建表。
或者您可以删除并重新创建该列:

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

编辑或者您可以Switch Identity On/Off With A Custom Migration Operation

相关问题