实体框架6代码第一个int第一行的标识列值为零 [英] Entity Framework 6 Code First int Identity column value is zero for first row

查看:148
本文介绍了实体框架6代码第一个int第一行的标识列值为零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在第一次执行update-database命令以使用种子数据填充数据库之后:



发现所有int id列以零(0)开头,而不是预期的一个(1)。



在Configuration.cs的Seed方法的顶部,为每个实体/表添加以下2行代码:



[注意:由于外键约束,我删除了后代表中的所有行,然后在祖先链上工作。]

  context.Database.ExecuteSqlCommand(从Widgets中删除); 
context.Database.ExecuteSqlCommand(DBCC CHECKIDENT('Widgets',RESEED,0));

然后,我重新安装update-database,所有的int id列以一(1)



如果我删除数据库,请运行/添加初始迁移,然后运行update-database,所有int id列以零(0)开头。 p>

就像$ code> DBCC CHECKIDENT('Widgets',RESEED,0) SQL语句没有被执行运行Seed方法的时间。



此外,如果实体/表中没有种子数据,则update-database命令的次数无关紧要运行,第一次将一行添加到空表中,Id将为零(0)。



可能的是,有一种方法来指定初始种子值对于 OnModelCreating 方法中的int标识列 IdentityModels.cs



更新:


  1. 已更改: DBCC CHECKIDENT 表,RESEED,0) DBCC CHECKI DENT('Table',RESEED,1)


  2. 删除数据库。


  3. 执行: update-database -TargetMigration初始化(结果是所有int id以1开头。)


  4. 执行 update-database 以重置数据库。 (结果是所有的int Ids从2开始,无论你运行多少次 update-database 。)



解决方案

您的具体迁移类应该如下所示:

  public class 201707132034165_MyAwesomeDbInitial:DbMigration 
{
#region< Methods>

public override void Up()
{
CreateTable(
dbo.HasOverdrive,
c => new
{
HasOverdriveId = c.Int(nullable:false,identity:true),
HasOverdriveValue = c.String(nullable:false,maxLength:5)
})
.PrimaryKey(t = > t.HasOverdriveId)
.Index(t => t.HasOverdriveValue,unique:true,name:UX_HasOverdrive_AlternateKey);
}

//这应该由你的DbConfiguration类调用
public void Seed(MyAwesomeDbContext context)
{
//这是第一个! !!!!!!!!!!!!!
context.Database.ExecuteSqlCommand(DBCC CHECKIDENT('HasOverdrive',RESEED,0));

// LOOKUPS
SeedHasOverdrive(context);
}

private void SeedHasOverdrive(MeasurementContractsDbContext context)
{
context.HasOverdrive.AddOrUpdate

m => m.Id,
new HasOverdrive {HasOverdriveId = 0,HasOverdriveValue =No},// 0 = FALSE
new HasOverdrive {HasOverdriveId = 1,HasOverdriveValue =Yes} // 1 = TRUE
) ;
}

#endregion
}


After the first execution of the update-database command to populate the database with seed data:

Found that all int Id columns started with zero (0) rather than the expected one (1).

Added the following 2 lines of code for each entity/table to the top of the Seed method in Configuration.cs:

[Note: Because of the foreign key constraints, I deleted all rows in descendent tables, and then worked my way up the ancestral chain.]

context.Database.ExecuteSqlCommand("delete from Widgets");
context.Database.ExecuteSqlCommand("DBCC CHECKIDENT ('Widgets', RESEED, 0)");

Then, I reran update-database, and all of the int Id columns started with one (1).

If I drop the database, run/add the initial migration and then run update-database, all of the int Id columns start with zero (0).

It is as if the DBCC CHECKIDENT ('Widgets', RESEED, 0) SQL statements are not being executed the first time that the Seed method is run.

Also, if there is no seed data for an entity/table, it does not matter how many times the update-database command is run, the first time a row is added to the empty table, the Id will be zero (0).

Possibly, is there a way to specify the initial seed value for int Identity columns in the override OnModelCreating method of IdentityModels.cs?

Update:

  1. Changed: DBCC CHECKIDENT ('Table', RESEED, 0) to DBCC CHECKIDENT ('Table', RESEED, 1) in Configuration.cs.

  2. Deleted the database.

  3. Executed: update-database -TargetMigration Initial (Result is all int Ids start with 1.)

  4. Executing update-database to reset the database. (Result is all int Ids start with 2, no matter how many times you run update-database.)

解决方案

Your concrete migration class should look "something" like the following:

public class 201707132034165_MyAwesomeDbInitial : DbMigration
{
    #region <Methods>

    public override void Up()
    {
        CreateTable(
            "dbo.HasOverdrive",
            c => new
            {
                HasOverdriveId = c.Int(nullable: false, identity: true),
                HasOverdriveValue = c.String(nullable: false, maxLength: 5)
            })
            .PrimaryKey(t => t.HasOverdriveId)
            .Index(t => t.HasOverdriveValue, unique: true, name: "UX_HasOverdrive_AlternateKey");
    }

    // This should is called by your DbConfiguration class
    public void Seed(MyAwesomeDbContext context)
    {
        // DO THIS FIRST !!!!!!!!!!!!!!!
        context.Database.ExecuteSqlCommand("DBCC CHECKIDENT ('HasOverdrive', RESEED, 0)");

        // LOOKUPS
        SeedHasOverdrive(context);
    }

    private void SeedHasOverdrive(MeasurementContractsDbContext context)
    {
        context.HasOverdrive.AddOrUpdate
        (
            m => m.Id,
            new HasOverdrive { HasOverdriveId = 0, HasOverdriveValue = "No" }, // 0 = FALSE 
            new HasOverdrive { HasOverdriveId = 1, HasOverdriveValue = "Yes" } // 1 = TRUE
        );
    }

    #endregion
}

这篇关于实体框架6代码第一个int第一行的标识列值为零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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