简体   繁体   English

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

[英]Multiple indexes possible using HasColumnAnnotation?

It looks like in Entity Framework 6.1 they added the ability to create table indexes via the new HasColumnAnnotation method. 它看起来像在Entity Framework 6.1中,它们添加了通过新的HasColumnAnnotation方法创建表索引的HasColumnAnnotation 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 ? 有没有人知道目前是否可以通过StringPropertyConfigurationPrimitivePropertyConfiguration上提供的新HasColumnAnnotation将多个索引添加到同一列?

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. 我可以通过在迁移脚本中手动添加索引来解决这个问题,但是最好能够在EntityTypeConfiguration映射中配置它,这样我就可以在一个位置完成所有操作。


After Gerts feedback, this is what I ended up doing: 在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));
    }
}

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

This is because each of your extension methods assign a new annotation to a property and overwrite the previous one. 这是因为每个扩展方法都会为属性分配一个新注释并覆盖前一个注释。 Let me show that by using your methods in an example. 让我通过在示例中使用您的方法来表明。

Say we have this (useless) class 假设我们有这个(无用的)课程

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

And apply your index definitions (skipping the part modelBuilder.Entity<Client>() ): 并应用您的索引定义(跳过部分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);

Inlining the extension methods (thank God for Resharper) this leads to 内联扩展方法(感谢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));

This is the same as writing 这和写作一样

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

and then replacing it by 然后替换

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

To reproduce the correct annotation... 要重现正确的注释......

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

...the configuration of the ClientId property should look like ... ClientId属性的配置应如下所示

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

Now suddenly creating extension methods is far less appealing. 现在突然创建扩展方法的吸引力要小得多。 It's hardly worth the effort to create one for this combined annotation. 为这个组合注释创建一个是不值得的。 But for single-use columns your methods are an improvement. 但对于一次性色谱柱,您的方法是一种改进。

Of course it is clear why you're trying this. 当然很清楚你为什么要这样做。 The current fluent syntax is clunky to say the least. 目前流畅的语法至少可以说是笨拙的。 The EF team knows this perfectly well and they're hoping for some contributor to grab this issue soon. EF团队非常了解这一点 ,他们希望有一些贡献者尽快解决这个问题。 Maybe something for you? 也许适合你的东西?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM