c# - 使用 HasColumnAnnotation 可能有多个索引?

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

这非常有效...直到我尝试创建第二个索引,其中包含已在另一个索引中使用的列。无论我最后添加什么都会覆盖原来的。有谁知道目前是否可以通过 StringPropertyConfigurationPrimitivePropertyConfiguration 上可用的新 HasColumnAnnotation 向同一列添加多个索引?

我可以像往常一样通过在迁移脚本中手动添加索引来解决这个问题,但是最好能够在 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))

最佳答案

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

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

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

现在突然创建扩展方法远没有那么吸引人了。几乎不值得为此组合注释创建一个。但是对于一次性色谱柱,您的方法是一种改进。

当然很清楚您为什么要这样做。目前的流利语法至少可以说是笨拙的。英孚团队knows this perfectly well他们希望一些贡献者尽快捕获这个问题。也许有什么适合你的?

关于c# - 使用 HasColumnAnnotation 可能有多个索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24337523/

相关文章:

entity-framework - 没有关键属性的复合PK

c# - 参数集合中已存在名为 'p__linq__0' 的参数。参数名称在参数集合中必须是唯一的

c# - 如何从外部 DLL 中保存复杂对象?

entity-framework - 自引用多对多关系EF代码优先

c# - C# : What part defines the public key? 中的 RSA 加密

c# - 这条IL指令中的-2是什么意思?

entity-framework - Entity Framework 4 - 将现有模型添加到关联中

asp.net - 如何在EF Code First中使用会籍提供者?

c# - DDD 使用事件或服务?

c# - List<BlockingCollection<T>> 线程安全吗?