错误更新数据库:要更改列的IDENTITY属性,需要删除并重新创建该列

问题描述 投票:1回答:1

当我尝试从程序包管理器控制台更新数据库时,出现以下错误。

要更改列的IDENTITY属性,需要删除并重新创建该列。

我意识到存在与此相同错误有关的问题,但是它们似乎涉及主键,因此有关IDENTITY的说明很有意义。我看不到IDENTITY在我的情况下如何应用,因为我要更改的列不是主键,也没有索引。

复制步骤

我的表定义如下:

CREATE TABLE [dbo].[Areas] (
    [Id]          INT            IDENTITY (1, 1) NOT NULL,
    [UserId]      NVARCHAR (450) NOT NULL,
    [Title]       NVARCHAR (150) NOT NULL,
    [Description] NVARCHAR (MAX) NULL,
    [CssClass]    NVARCHAR (32) NOT NULL, 
    [Sequence]    INT            NOT NULL,
    [OnHold]      BIT            NOT NULL,
    [Created]     DATE           NOT NULL,
    CONSTRAINT [PK_Areas] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Areas_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo]. [AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_Areas_UserId]
    ON [dbo].[Areas]([UserId] ASC);

我更改了模型,以便删除string CssClass,而是添加了int StyleId。但是,当我更新数据库时,出现上述错误。

因此,我如下手动编辑了表定义。

CREATE TABLE [dbo].[Areas] (
    [Id]          INT            IDENTITY (1, 1) NOT NULL,
    [UserId]      NVARCHAR (450) NOT NULL,
    [Title]       NVARCHAR (150) NOT NULL,
    [Description] NVARCHAR (MAX) NULL,
    [StyleId]     INT NOT NULL, 
    [Sequence]    INT            NOT NULL,
    [OnHold]      BIT            NOT NULL,
    [Created]     DATE           NOT NULL,
    CONSTRAINT [PK_Areas] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Areas_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo]. [AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_Areas_UserId]
    ON [dbo].[Areas]([UserId] ASC);

但是当我尝试再次更新数据库(以确保所有内容都同步)时,出现相同的错误。

更新输出

PM> update-database
Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 3.0.0 initialized 'ApplicationDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
Microsoft.EntityFrameworkCore.Database.Command[20100]
      Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Microsoft.EntityFrameworkCore.Database.Command[20100]
      Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT OBJECT_ID(N'[__EFMigrationsHistory]');
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [MigrationId], [ProductVersion]
FROM [__EFMigrationsHistory]
ORDER BY [MigrationId];
Microsoft.EntityFrameworkCore.Database.Command[20100]
      Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT [MigrationId], [ProductVersion]
      FROM [__EFMigrationsHistory]
      ORDER BY [MigrationId];
Microsoft.EntityFrameworkCore.Migrations[20402]
      Applying migration '20191230173411_StyleIdNowInt'.
Applying migration '20191230173411_StyleIdNowInt'.
System.InvalidOperationException: To change the IDENTITY property of a column, the column needs to be dropped and recreated.
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.Generate(AlterColumnOperation operation, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.<>c.<.cctor>b__71_4(MigrationsSqlGenerator g, MigrationOperation o, IModel m, MigrationCommandListBuilder b)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.Generate(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.Generate(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
   at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.Generate(IReadOnlyList`1 operations, IModel model)
   at Microsoft.EntityFrameworkCore.Migrations.SqlServerMigrationsSqlGenerator.Generate(IReadOnlyList`1 operations, IModel model)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.GenerateUpSql(Migration migration)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.<>c__DisplayClass15_2.<GetMigrationCommandLists>b__2()
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
To change the IDENTITY property of a column, the column needs to be dropped and recreated.

20191230173411_StyleIdNowInt

public partial class CssClassToStyleId : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropColumn(
            name: "Discriminator",
            table: "AspNetUsers");

        migrationBuilder.DropColumn(
            name: "CssClass",
            table: "Areas");

        migrationBuilder.AlterColumn<int>(
            name: "Id",
            table: "Areas",
            nullable: false,
            oldClrType: typeof(int),
            oldType: "int")
            .OldAnnotation("SqlServer:Identity", "1, 1");

        migrationBuilder.AddColumn<int>(
            name: "StyleId",
            table: "Areas",
            nullable: false,
            defaultValue: 0);
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropColumn(
            name: "StyleId",
            table: "Areas");

        migrationBuilder.AddColumn<string>(
            name: "Discriminator",
            table: "AspNetUsers",
            type: "nvarchar(max)",
            nullable: false,
            defaultValue: "");

        migrationBuilder.AlterColumn<int>(
            name: "Id",
            table: "Areas",
            type: "int",
            nullable: false,
            oldClrType: typeof(int))
            .Annotation("SqlServer:Identity", "1, 1");

        migrationBuilder.AddColumn<string>(
            name: "CssClass",
            table: "Areas",
            type: "nvarchar(32)",
            maxLength: 32,
            nullable: false,
            defaultValue: "");
    }
}

更新

我不知道为什么修改Areas.Id的块在那里。我看不出新类型与旧类型有何不同。无论如何,如果我将这些块注释掉,则会出现两个错误。

执行DbCommand失败(11ms)[Parameters = [],CommandType ='Text',CommandTimeout = '30']声明@ var1 sysname;SELECT @ var1 = [d]。[名称]从[sys]。[default_constraints] [d]内联接[sys]。[列] [c]在[d]上。[parent_column_id] = [c]。[column_id]和[d]。[parent_object_id] = [c]。[object_id]在哪里([d]。[parent_object_id] = OBJECT_ID(N'[Areas]')AND [c]。[name] = N'CssClass');如果@ var1不为空EXEC(N'ALTER TABLE [Areas] DROP CONSTRAINT ['+ @ var1 +'];');ALTER TABLE [区域] DROP列[CssClass];

ALTER TABLE DROP COLUMN失败,因为表'Areas'中不存在列'CssClass'。

entity-framework asp.net-core ef-code-first ef-migrations razor-pages
1个回答
0
投票

出现此错误的原因是,当内部已经有一些记录时,您试图改变表中列的类型。

所以可以说col css是ABC,并且您希望将col css类型设置为int,除非删除这些记录,否则您将无法更新表,因为ABC不会转换为int类型。

您可以配置EF并启用自动迁移并启用allowdataloss,因此在更新数据库时不会出现错误,但是,因为启用了dataloss,您将丢失记录的数据。

下面的代码到DbContext构造函数

Database.SetInitializer(new CreateDatabaseIfNotExists<MPContext>());
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MPContext, Configuration>());

并在配置文件中添加

AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
© www.soinside.com 2019 - 2024. All rights reserved.