在我的模式定义中重构​​许多HasColumnAnnotation和IndexAnnotation用法

时间:2014-10-09 16:31:34

标签: c# entity-framework lambda

我有许多代码块,如下所示:

modelBuilder
    .Entity<Foo>()
    .Property(t => t.X)
    .IsRequired()
    .HasMaxLength(60)
    .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_X_Y", 1) { IsUnique = true }));

modelBuilder
    .Entity<Foo>()
    .Property(t => t.Y)
    .IsRequired()
    .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_X_Y", 2) { IsUnique = true }));

此块通过流畅的API告诉EF在表X上创建一个包含YFoo列的唯一索引。

另外一段代码就是这样,表R上的列SBar

modelBuilder
    .Entity<Bar>()
    .Property(t => t.R)
    .IsRequired()
    .HasMaxLength(60)
    .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_R_S", 1) { IsUnique = true }));

modelBuilder
    .Entity<Bar>()
    .Property(t => t.S)
    .IsRequired()
    .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_R_S", 2) { IsUnique = true }));

我想重构这个,所以它最终看起来像:

CreateCompositeUnique<Foo>(modelBuilder, "IX_X_Y", t => new {t.X, t.Y});
CreateCompositeUnique<Bar>(modelBuilder, "IX_R_S", t => new {t.R, t.S});

我在考虑这样的事情:

private void CreateCompositeUnique<T>(DbModelBuilder modelBuilder, string indexName, List<Expression<Func<T, byte[]>>> properties)
{ 
    for (int i = 0; i < properties.Count; i++)
    {
        modelBuilder
        .Entity<typeof(T)>()
        .Property(properties[i])
        .IsRequired() 
        .HasMaxLength(60)  // --only when propery is string
        .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute(indexName, i) { IsUnique = true }));
    }
}

但我有一些问题:

  1. 这是个好主意吗?
  2. 我如何知道该属性是否为字符串?
  3. 传递参​​数的最佳方法是什么?
  4. 如何访问“T”?我在.Entity<typeof(T)>
  5. 收到编译错误

1 个答案:

答案 0 :(得分:2)

按照Gert Arnold的建议,我创建了一个扩展方法。实际上它们是两种扩展方法(为什么?autoexplicative,参见代码注释)

public static class ExtensionMethods
{
    public static StringPropertyConfiguration HasIndex(this StringPropertyConfiguration config, string indexName, int i)
    {
        return config.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation((new IndexAttribute(indexName, i) { IsUnique = true })));
    }

    public static PrimitivePropertyConfiguration HasIndex(this PrimitivePropertyConfiguration config, string indexName, int i)
    {
        return config.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation((new IndexAttribute(indexName, i) { IsUnique = true })));
    }
}

用法是这样的:

modelBuilder
    .Entity<Foo>()
    .Property(t => t.X)
    .IsRequired()
    .HasMaxLength(60)
    .HasIndex("IX_X_Y", 1); // <-- here (X is string)

modelBuilder
    .Entity<Foo>()
    .Property(t => t.Y)
    .IsRequired()
    .HasIndex("IX_X_Y", 2); // <-- and here (Y is a primitive)