使用Entity Framework手动输入密钥 [英] Entering keys manually with Entity Framework

查看:93
本文介绍了使用Entity Framework手动输入密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用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;组; }

public string EventType {get;组; } // TODO:Event Type Table on
public DateTime StartDate {get;组; }
public DateTime EndDate {get;组; }

public virtual ICollection< Match>比赛{get;组; }
public virtual ICollection< EventParticipation>活动参与{get;组;
}

提前感谢

解决方案

默认情况下,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 put t他在迁移中:

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

生成的sql是这样的: / p>

ALTER TABLE [dbo]。[事件] ALTER COLUMN [EventID] [int] NOT NULL



哪个实际上是溺水的蹲下。 从列中删除IDENTITY 不是不重要的。您需要删除并重新创建表或创建一个新列,那么您必须复制数据并修复外键。所以这并不奇怪,EF并没有为你做这件事。



您需要了解如何最好地为自己做这件事。您可以将您的迁移回滚到0,然后从头开始重新构建,您可以指定 DatabaseGeneratedOption.None ,或者您可以手动更改迁移以删除并重新创建表。



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

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

编辑
或者你可以使用自定义迁移操作切换标识开/关/ a>


I'm trying to use Entity Framework code first for a simple database project and I run into a problem I simply cannot figure out.

I noticed EF was setting the ID for my tables automatically increasing by 1 each time, completely ignoring the value I entered manually for that field. After some searching it is my understanding that the right way to disable this behavior is doing:

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

However now I'm just getting this error and I have no idea why:

Unhandled Exception: System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---

System.Data.UpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Cannot insert explicit value for identity column in table 'Events' when IDENTITY_INSERT is set to OFF.

If it's helpful, here is the POCO class in question:

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

Thanks in advance.

解决方案

By default Entity Framework assumes that an integer primary key is database generated (equivalent to adding the attribute HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) or calling Property(e => e.EventID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); in the Fluent API.

If you look at the migration that creates the table you should see this:

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

Then you changed the model using the Fluent API to DatabaseGenerated.None. EF puts this in the migration:

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

And the sql generated is this:

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

Which actually does diddly squat. Dropping the IDENTITY from a column is not trivial. You need to drop and recreate the table or create a new column, then you have to copy the data and fix up foreign keys. So it's not surprising that EF isn't doing that for you.

You need to work out how best to do it for yourself. You could roll back your migrations to 0 and re-scaffold from scratch now that you have specified DatabaseGeneratedOption.None, or you could change the migration manually to drop and recreate the table.

Or you could drop and recreate the column:

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

EDIT Or you could Switch Identity On/Off With A Custom Migration Operation

这篇关于使用Entity Framework手动输入密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆