将实体框架升级到6.1 -索引已经存在错误

本文关键字:索引 错误 存在 框架 实体 | 更新日期: 2023-09-27 17:50:49

我刚刚将一个代码优先模型的项目从Entity Framework 6.0.2升级到6.1.0。

升级后,context.Database.CompatibleWithModel(true)返回false, EF认为数据库不再与模型兼容。我没有改变任何东西,只是升级了EF。

我运行Add-Migration看看会发生什么,EF创建了一个大迁移,似乎在每个表的每个外键属性上创建了一个索引:

    public override void Up()
    {
        CreateIndex("dbo.ActivityStreams", "UserId");
        CreateIndex("dbo.Users", "OfficeId");
        CreateIndex("dbo.Offices", "ParentId");
        CreateIndex("dbo.Rosters", "UserId");
        ...and many more similar lines...

我猜这与EF 6.1的新索引特性有关?有点奇怪,不过还好。

当我Update-Database应用新的迁移时,出现索引已经存在的错误。查看数据库和以前的迁移,几乎所有的索引确实已经存在。

我哪里做错了?有升级EF的程序吗?

将实体框架升级到6.1 -索引已经存在错误

正如在其他答案中提到的,这是由于实体框架的错误。将DropIndex代码复制到Up方法的公认答案会对数据库造成不必要的工作。相反,我建议正确的做法是删除UpDown方法的内容,因为这些索引已经存在,不需要删除。

我也有同样的问题。我通过重新创建索引来修复它。

我通过将迁移中的Down方法中的DropIndexes复制粘贴到Up方法中来完成此操作。因此,首先要删除索引,然后重新创建索引。不知道为什么这是必要的,但它解决了问题。

Re:您的外键正在创建中,我在以下链接中发现了以下信息:

http://blog.oneunicorn.com/2014/02/15/ef-6-1-creating-indexes-with-indexattribute/声明如下:

ForeignKeyIndexConvention Code First约定导致为模型中任何外键的列创建索引,除非这些列已经使用IndexAttribute指定了索引。如果您不希望为您的fk创建索引,您可以删除此约定:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove<ForeignKeyIndexConvention>();
}

EF核心6

1-添加CreateIndexIfNotExists扩展方法

using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
public static OperationBuilder<SqlOperation> CreateIndexIfNotExists(
        this MigrationBuilder migrationBuilder,
        string name,
        string table,
        string column)
    {
        return migrationBuilder.Sql(@$"IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = '{name}')
                        BEGIN
                            CREATE NONCLUSTERED INDEX [{name}] ON [dbo].[{table}]
                            (
                            [{column}] ASC
                            ) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
                        END
        ");
    }

2-改变你的向上迁移方法使用CreateIndexIfNotExists

public partial class Add_Index_TableName_ColumnName : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    { 
        migrationBuilder.CreateIndexIfNotExists(
            name: "IX_TableName_ColumName",
            table: "TableName",
            column: "ColumName");
    }

3-在迁移

中为down方法执行类似的代码