简体   繁体   English

Entity Framework Core:无法在生产服务器上运行迁移脚本,聚集索引的最大键长度为 900 字节

[英]Entity Framework Core: Unable to run migration script on production server, The maximum key length for a clustered index is 900 bytes

I'm trying to deploy my ASP.NET Core website on a production server, hosted with Plesk.我正在尝试在由 Plesk 托管的生产服务器上部署我的 ASP.NET Core 网站。 I have 2 projects in my solution: 1 containing my DbContext , 1 containing my web project.我的解决方案中有 2 个项目:1 个包含我的DbContext ,1 个包含我的 Web 项目。

I generated migrations for my DbContext :我为我的DbContext生成了迁移:

dotnet ef migrations add AddIdentity --project ..\MyProject.Data

Then I generated a production migration script as mentioned in the docs ( https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet#dotnet-ef-migrations-script )然后我生成了文档中提到的生产迁移脚本( https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet#dotnet-ef-migrations-script

dotnet ef migrations script --idempotent --output "MigrationScripts\AddIdentity.sql" --context MyDbContext --project ..\MyProject.Data

Then I navigated to the SQL utility on my production server (MyLittleAdmin) and pasted the generated SQL script in it.然后我导航到生产服务器 (MyLittleAdmin) 上的 SQL 实用程序并将生成的 SQL 脚本粘贴到其中。 This succeeds but I get the following error:这成功了,但我收到以下错误:

Warning!警告! The maximum key length for a clustered index is 900 bytes.聚集索引的最大键长度为 900 字节。 The index 'PK_AspNetUserLogins' has maximum length of 1800 bytes.索引“PK_AspNetUserLogins”的最大长度为 1800 字节。 For some combination of large values, the insert/update operation will fail.对于某些大值组合,插入/更新操作将失败。

Warning!警告! The maximum key length for a clustered index is 900 bytes.聚集索引的最大键长度为 900 字节。 The index 'PK_AspNetUserTokens' has maximum length of 1804 bytes.索引“PK_AspNetUserTokens”的最大长度为 1804 字节。 For some combination of large values, the insert/update operation will fail.对于某些大值组合,插入/更新操作将失败。

If ignoring this error, I would probably get in trouble later on with queries failing for "no apparent reason" (this reason).如果忽略此错误,稍后我可能会遇到查询因“没有明显原因”(这个原因)而失败的麻烦。

My code is very straightforward:我的代码非常简单:

internal class MintPlayerContext : IdentityDbContext<User, Role, int>
{
    private readonly IConfiguration configuration;
    public MintPlayerContext(IConfiguration configuration) : base()
    {
        this.configuration = configuration;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.UseSqlServer(configuration.GetConnectionString("MintPlayer"), options => options.MigrationsAssembly("MintPlayer.Data"));
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}

internal class User : IdentityUser<int>
{
    public string PictureUrl { get; set; }
}

internal class Role : IdentityRole<int>
{
}

I also tried using Guid's (I want to use Guids eventually) but even with int's MyLittleAdmin complaints about the Key being too long.我也尝试过使用 Guid(我最终想使用 Guid),但即使 int 的 MyLittleAdmin 抱怨 Key 太长。 I already checked on Google but this only gives diagnostic articles and does not really provide a solution.我已经在谷歌上查过,但这只是提供诊断文章,并没有真正提供解决方案。

Right now this is the AspNetUsers section of the migration:现在这是迁移的 AspNetUsers 部分:

CREATE TABLE [AspNetUsers] (
    [Id] int NOT NULL IDENTITY,
    [UserName] nvarchar(256) NULL,
    [NormalizedUserName] nvarchar(256) NULL,
    [Email] nvarchar(256) NULL,
    [NormalizedEmail] nvarchar(256) NULL,
    [EmailConfirmed] bit NOT NULL,
    [PasswordHash] nvarchar(max) NULL,
    [SecurityStamp] nvarchar(max) NULL,
    [ConcurrencyStamp] nvarchar(max) NULL,
    [PhoneNumber] nvarchar(max) NULL,
    [PhoneNumberConfirmed] bit NOT NULL,
    [TwoFactorEnabled] bit NOT NULL,
    [LockoutEnd] datetimeoffset NULL,
    [LockoutEnabled] bit NOT NULL,
    [AccessFailedCount] int NOT NULL,
    [PictureUrl] nvarchar(max) NULL,
    CONSTRAINT [PK_AspNetUsers] PRIMARY KEY ([Id])
);

What can I do to solve this?我能做些什么来解决这个问题?

Edit:编辑:

I tried modifying my DbContext configuration to force the Key to be only the Id:我尝试修改我的 DbContext 配置以强制 Key 仅为 Id:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<User>().HasKey(u => u.Id);
    modelBuilder.Entity<Role>().HasKey(r => r.Id);
}

This seems to affect the migration indeed:这似乎确实影响了迁移:

[Id] int NOT NULL IDENTITY,

Instead of:代替:

[Id] uniqueidentifier NOT NULL,

But it still gives the same error但它仍然给出同样的错误

Edit: Adding the AspNetUserLogins, AspNetUserRoles, stripped the if's编辑:添加 AspNetUserLogins、AspNetUserRoles,去掉 if 的

CREATE TABLE [AspNetUserLogins] (
    [LoginProvider] nvarchar(450) NOT NULL,
    [ProviderKey] nvarchar(450) NOT NULL,
    [ProviderDisplayName] nvarchar(max) NULL,
    [UserId] int NOT NULL,
    CONSTRAINT [PK_AspNetUserLogins] PRIMARY KEY ([LoginProvider], [ProviderKey]),
    CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE
);

CREATE TABLE [AspNetUserTokens] (
    [UserId] int NOT NULL,
    [LoginProvider] nvarchar(450) NOT NULL,
    [Name] nvarchar(450) NOT NULL,
    [Value] nvarchar(max) NULL,
    CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY ([UserId], [LoginProvider], [Name]),
    CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE
);

You can try changing it to:您可以尝试将其更改为:

CREATE TABLE [AspNetUserTokens] (
    [UserId] int NOT NULL,
    [LoginProvider] nvarchar(150) NOT NULL,
    [Name] nvarchar(150) NOT NULL,
    [Value] nvarchar(150) NULL,
    CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY ([UserId], [LoginProvider], [Name]),
    CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE
);

I think Name cant contain more than 150 characters.我认为名称不能包含超过 150 个字符。 I mean its just a Name.我的意思是它只是一个名字。

Total length of all columns need to be < than 900.所有列的总长度需要小于 900。

ALTER TABLE sampleTable ALTER COLUMN column1 VARCHAR (400) NULL;
ALTER TABLE sampleTable ALTER COLUMN column2 VARCHAR (200) NULL;
ALTER TABLE sampleTable ALTER COLUMN column3 VARCHAR (200) NULL;

As per comments, you should try external Oauth provides and come up with a reasonable number.根据评论,您应该尝试外部 Oauth 提供并提出一个合理的数字。

also, storage size of nvarchar is *2.此外,nvarchar 的存储大小为 *2。 450 * 2 will trigger the error. 450 * 2 将触发错误。 you can try reducing it.你可以尝试减少它。

AspNetUserLogins and AspNetUserTokens need a shorter key defined. AspNetUserLoginsAspNetUserTokens需要定义一个较短的键。 I'm assuming that no key was defined in the model, so all columns were added to the key.我假设模型中没有定义任何键,所以所有列都被添加到键中。 Perhaps including some large string columns.也许包括一些大的字符串列。

Thanks everyone, It was spot-on.谢谢大家,很及时。 Thanks to all of your suggestions I managed to get it working.感谢您的所有建议,我设法让它发挥作用。

Since I'm using Code-first, I can't just modify my generated migrations.由于我使用的是 Code-first,我不能只修改我生成的迁移。 So this is what I've done:所以这就是我所做的:

internal class MintPlayerContext : IdentityDbContext<User, Role, int>
{
    // dotnet ef migrations add AddIdentity --project ..\MyProject.Data
    // dotnet ef database update --project ..\MyProject.Data
    // (only looks at your appsettings.json file, not your appsettings.*.json, so for local development)

    // To generate production migrations
    // dotnet ef migrations script --idempotent --output "MigrationScripts\AddIdentity.sql" --context MyDbContext --project ..\MyProject.Data

    private readonly IConfiguration configuration;
    public MintPlayerContext(IConfiguration configuration) : base()
    {
        this.configuration = configuration;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.UseSqlServer(configuration.GetConnectionString("MyProject"), options => options.MigrationsAssembly("MyProject.Data"));
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Microsoft.AspNetCore.Identity.IdentityUserLogin<int>>()
            .Property(ut => ut.LoginProvider)
            .HasMaxLength(50);
        modelBuilder.Entity<Microsoft.AspNetCore.Identity.IdentityUserLogin<int>>()
            .Property(ut => ut.ProviderKey)
            .HasMaxLength(200);

        modelBuilder.Entity<Microsoft.AspNetCore.Identity.IdentityUserToken<int>>()
            .Property(ut => ut.LoginProvider)
            .HasMaxLength(50);
        modelBuilder.Entity<Microsoft.AspNetCore.Identity.IdentityUserToken<int>>()
            .Property(ut => ut.Name)
            .HasMaxLength(50);
    }
}

I will be using Guid's in order to not make UserIds guess-able.我将使用 Guid's 为了不让 UserIds 被猜测。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 Entity Framework Core 运行迁移 SQL 脚本 - How to run migration SQL script using Entity Framework Core 消息 = “操作失败。 索引 &#39;IX_companyinfo_exhibition&#39; 的长度为 904 字节的索引条目超过了 900 字节的最大长度。” - Message = “Operation failed. The index entry of length 904 bytes for the index 'IX_companyinfo_exhibition' exceeds the maximum length of 900 bytes.” 如何解决错误“索引&#39;IX_companyinfo_exhibition&#39;的长度为904字节的索引条目超过了最大长度900字节。” - How to resolve the error "The index entry of length 904 bytes for the index 'IX_companyinfo_exhibition' exceeds the maximum length of 900 bytes." 在Entity Framework Core中创建非聚集索引 - Create a non-clustered index in Entity Framework Core 将聚簇索引与主键分离的实体框架 - Entity Framework separating clustered index from primary key 在运行时在 .Net Core 中创建和应用迁移 - Entity Framework Core - Create and Apply Migration at run time in .Net Core - Entity Framework Core “脚本迁移”可以在 .NET Entity Framework Core 中创建数据库吗? - Can "Script-Migration" create the database in .NET Entity Framework Core? Entity Framework Core 中的种子脚本正在破坏我的迁移 - Seed script in Entity Framework Core is breaking my migration 在Entity Framework 6.1(非Core)中,如何使用IndexAttribute定义聚簇索引? - In Entity Framework 6.1 (not Core), how can I use the IndexAttribute to define a clustered index? Entity Framework Core 迁移是否会影响 SQL 服务器索引? - Is Entity Framework Core migration can affect SQL Server indexes?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM