17

It looks like in Entity Framework 6.1 they added the ability to create table indexes via the new HasColumnAnnotation method. I created a few helper extensions to speed up the process:

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 }));
    }
}

This works fantastic...until I try to create a second index that contains a column already used in another index. Whatever I add last overwrites the original. Does anyone know if it is currently possible to add multiple indexes to the same column via the new HasColumnAnnotation available on the StringPropertyConfiguration and PrimitivePropertyConfiguration?

I can work around this like I always have by manually adding indexes in the Migration scripts, but it would be most excellent to be able to configure this in the EntityTypeConfiguration mappings so I can have it all in one spot.


After Gerts feedback, this is what I ended up doing:

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));
    }
}

And here is the new usage:

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

1 回答 1

31

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

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

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);

内联扩展方法(感谢上帝的 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 团队非常清楚这一点,他们希望一些贡献者能尽快解决这个问题。也许给你一些东西?

于 2014-06-21T22:48:04.163 回答