当我尝试从程序包管理器控制台更新数据库时,出现以下错误。
要更改列的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.
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'。
出现此错误的原因是,当内部已经有一些记录时,您试图改变表中列的类型。
所以可以说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;