使用HasColumnAnnotation可以实现多个索引?

时间:2014-06-21 01:40:46

标签: c# entity-framework ef-code-first ef-fluent-api

在Entity Framework 6.1中,它们添加了通过新的HasColumnAnnotation方法创建表索引的功能。我创建了一些辅助扩展来加速这个过程:

public static class MappingExtensions
{
    public static StringPropertyConfiguration HasIndex(this StringPropertyConfiguration config, bool isUnique = false)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute() { IsUnique = isUnique }));
    }
    public static StringPropertyConfiguration HasIndex(this StringPropertyConfiguration config, string name, int order = 1, bool isUnique = false)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute(name, order) { IsUnique = isUnique }));
    }
    public static PrimitivePropertyConfiguration HasIndex(this PrimitivePropertyConfiguration config, bool isUnique = false)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute() { IsUnique = isUnique }));
    }
    public static PrimitivePropertyConfiguration HasIndex(this PrimitivePropertyConfiguration config, string name, int order = 1, bool isUnique = false)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute(name, order) { IsUnique = isUnique }));
    }
}

这很棒......直到我尝试创建第二个索引,其中包含已在另一个索引中使用过的列。无论我添加什么,最后覆盖原始。有谁知道目前是否可以通过HasColumnAnnotationStringPropertyConfiguration上提供的新PrimitivePropertyConfiguration将多个索引添加到同一列?

我可以通过在迁移脚本中手动添加索引来解决这个问题,但是最好能够在EntityTypeConfiguration映射中配置它,这样我就可以在一个地方完成所有操作


在Gerts反馈之后,这就是我最终做的事情:

public static class MappingExtensions
{
    public static StringPropertyConfiguration HasIndex(this StringPropertyConfiguration config, params IndexAttribute[] indexes)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(indexes));
    }

    public static PrimitivePropertyConfiguration HasIndex(this PrimitivePropertyConfiguration config, params IndexAttribute[] indexes)
    {
        return config.HasColumnAnnotation("Index", new IndexAnnotation(indexes));
    }
}

以下是新用法:

Property(x => x.Name).IsRequired().HasMaxLength(65).HasIndex(new IndexAttribute("IX_Countries_Name") { IsUnique = true }, new IndexAttribute("IX_Countries_Published", 2))

1 个答案:

答案 0 :(得分:29)

这是因为每个扩展方法都会为属性分配一个新注释并覆盖前一个注释。让我通过在示例中使用您的方法来表明。

假设我们有这个(无用的)类

public class Client
{
    public int ClientId { get; set; }
    public int CompanyId { get; set; }
    public int AddressId { get; set; }
}

并应用您的索引定义(跳过部分modelBuilder.Entity<Client>()):

.Property(c => c.ClientId).HasIndex("ClientCompanyIndex");
.Property(c => c.CompanyId).HasIndex("ClientCompanyIndex", 2);
.Property(c => c.ClientId).HasIndex("ClientAddressIndex");
.Property(c => c.AddressId).HasIndex("ClientAddressIndex", 2);

内联扩展方法(感谢God for Resharper)这导致了

.Property(c => c.ClientId).HasColumnAnnotation("Index",
    new IndexAnnotation(new IndexAttribute("ClientCompanyIndex", 1));
.Property(c => c.CompanyId).HasColumnAnnotation("Index",
     new IndexAnnotation(new IndexAttribute("ClientCompanyIndex", 2));
.Property(c => c.ClientId).HasColumnAnnotation("Index",
    new IndexAnnotation(new IndexAttribute("ClientAddressIndex", 1));
.Property(c => c.AddressId).HasColumnAnnotation("Index",
     new IndexAnnotation(new IndexAttribute("ClientAddressIndex", 2));

这与写作

相同
[Index("ClientCompanyIndex", Order = 1)]
public int ClientId { get; set; }

然后通过

替换
[Index("ClientAddressIndex", Order = 1)]
public int ClientId { get; set; }

重现正确的注释...

[Index("ClientAddressIndex", IsUnique = true, Order = 1)]
[Index("ClientCompanyIndex", IsUnique = true, Order = 1)]
public int ClientId { get; set; }
[Index("ClientCompanyIndex", IsUnique = true, Order = 2)]
public int CompanyId { get; set; }
[Index("ClientAddressIndex", IsUnique = true, Order = 2)]
public int AddressId { get; set; }

... ClientId属性的配置应该类似于

.Property(c => c.ClientId).HasColumnAnnotation("Index",
    new IndexAnnotation(new[]
        {
            new IndexAttribute("ClientCompanyIndex", 1),
            new IndexAttribute("ClientAddressIndex", 1)
        }));

现在突然创建扩展方法的吸引力要小得多。为这个组合注释创建一个是不值得的。但对于一次性色谱柱,您的方法是一种改进。

当然很清楚你为什么要这样做。目前流畅的语法至少可以说是笨拙的。 EF团队knows this perfectly well和他们希望很快就会抓住这个问题。也许是适合你的东西?