实体框架索引生成错误

时间:2018-07-31 08:07:46

标签: c# entity-framework-6

我正在尝试创建2个这样的索引:

modelBuilder.Entity<MyEntity>()
    .HasIndex(p => new { p.Column1, p.Column2, p.Column3, p.Column4 })
    .HasName("ix_index1")
    .IsUnique();

modelBuilder.Entity<MyEntity>()
    .HasIndex(p => new { p.Column1, p.Column2, p.Column3 })
    .HasName("ix_index2")
    .IsUnique();

运行命令add-migration InitialCreate后得到的脚本是:

CreateTable(
    "DEV.MyEntity",
    c => new
        {
            Column1 = c.String(nullable: false, maxLength: 10),
            Column2 = c.Decimal(nullable: false, precision: 19, scale: 0),
            Column3 = c.Decimal(nullable: false, precision: 10, scale: 0),
            Column4 = c.Decimal(nullable: false, precision: 10, scale: 0),
        })
    .PrimaryKey(t => new { t.Column1, t.Column2, t.Column3 })
    .Index(t => new { t.Column1, t.Column2, t.Column3 }, unique: true, name: "ix_index2")
    .Index(t => t.Column4, unique: true, name: "ix_index1");

是否有原因为什么索引ix_index1中的所有列中只有Column4?预期结果是ix_index1适用于4列。

如果相关,那么我正在使用托管的Oracle数据库提供程序。实体框架版本6.2。

2 个答案:

答案 0 :(得分:2)

看起来像EF6错误(我想尝试优化冗余索引)。数据库提供程序无关(与SqlServer提供程序相同)。

一种错误的行为是您描述的行为。另一个是如果您交换两个HasIndex调用的顺序,则生成的迁移包含正确的ix_index1,但根本没有ix_index2

由于这是一个错误,除了向EF6问题跟踪器报告问题并等待最终解决该问题外,没有其他可做的事情。

但是,如果(Column1, Column2, Column2)是迁移所指示的PK,则ix_index2是多余的,您可以安全地从流畅的配置中删除它,这将允许正确生成{{1} }。

答案 1 :(得分:1)

好吧,由于我最初尝试的方法被确认由于错误而被破坏-我能够找到另一种解决方案,该方法似乎可以正常工作,但更加肮脏。

例如,假设您要创建四个索引,如下所示:

modelBuilder.Entity<MyEntity2>()
    .HasIndex(p => new { p.Column1, p.Column2, p.Column3, p.Column5 })
    .HasName("ix_1")
    .IsUnique();

modelBuilder.Entity<MyEntity2>()
    .HasIndex(p => new { p.Column1, p.Column2, p.Column4, p.Column5 })
    .HasName("ix_2")
    .IsUnique();

modelBuilder.Entity<MyEntity2>()
    .HasIndex(p => new { p.Column1, p.Column2, p.Column3 })
    .HasName("ix_3")
    .IsUnique();

modelBuilder.Entity<MyEntity2>()
    .HasIndex(p => new { p.Column1, p.Column2, p.Column4 })
    .HasName("ix_4")
    .IsUnique();

结果(截至撰写本文的31.07.04)将被破坏。

要正确创建所有索引,必须改用以下方法:

modelBuilder.Entity<MyEntity2>()
    .Property(e => e.Column1)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName,
        new IndexAnnotation(new[]
        {
            new IndexAttribute("ix_3", 1) { IsUnique = true },
            new IndexAttribute("ix_4", 1) { IsUnique = true },
            new IndexAttribute("ix_2", 1) { IsUnique = true },
            new IndexAttribute("ix_1", 1) { IsUnique = true }
        }));

modelBuilder.Entity<MyEntity2>()
    .Property(e => e.Column2)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName,
        new IndexAnnotation(new[]
        {
            new IndexAttribute("ix_3", 2) { IsUnique = true },
            new IndexAttribute("ix_4", 2) { IsUnique = true },
            new IndexAttribute("ix_2", 2) { IsUnique = true },
            new IndexAttribute("ix_1", 2) { IsUnique = true }
        }));

modelBuilder.Entity<MyEntity2>()
    .Property(e => e.Column3)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName,
        new IndexAnnotation(new[]
        {
            new IndexAttribute("ix_3", 3) { IsUnique = true },
            new IndexAttribute("ix_1", 3) { IsUnique = true }
        }));

modelBuilder.Entity<MyEntity2>()
    .Property(e => e.Column4)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName,
        new IndexAnnotation(new[]
        {
            new IndexAttribute("ix_4", 3) { IsUnique = true },
            new IndexAttribute("ix_2", 3) { IsUnique = true },
        }));

modelBuilder.Entity<MyEntity2>()
    .Property(e => e.Column5)
    .HasColumnAnnotation(
        IndexAnnotation.AnnotationName,
        new IndexAnnotation(new[]
        {
            new IndexAttribute("ix_2", 4) { IsUnique = true },
            new IndexAttribute("ix_1", 4) { IsUnique = true },
        }));

我希望我不会弄乱任何数字。但是这个主意应该是可以理解的。