在 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 }));
}
}
这非常有效...直到我尝试创建第二个索引,其中包含已在另一个索引中使用的列。无论我最后添加什么都会覆盖原来的。有谁知道目前是否可以通过 StringPropertyConfiguration
和 PrimitivePropertyConfiguration
上可用的新 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/