实体框架CodeFirst动态映射

时间:2014-03-12 14:04:14

标签: c# entity-framework ef-code-first

所以我使用了CodeFirst'实体框架的方法论和我有映射文件来映射表信息并添加诸如验证之类的东西,例如:

this.Property(t => t.AccountName)
            .IsRequired()
            .HasMaxLength(25);

这是使用Fluent API,我想知道如何通过字符串而不是t.AccountName获取属性名称。我想动态设置这些属性,而我只是不知道如何以编程方式执行此操作。

1 个答案:

答案 0 :(得分:2)

如果没有评论这是否可取(!),那么可以实现您的需求,因为Property()方法将表达式树作为其参数。请考虑以下事项:

public class MyEntity
{
    [Key]
    public int MyEntityId { get; set; }

    public string MyProperty { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<MyEntity> MyEntities
    {
        get { return this.Set<MyEntity>(); }
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        var param = Expression.Parameter(typeof(MyEntity));

        var propertyExpression = Expression.Lambda(Expression.Property(param, "MyProperty"), param);

        modelBuilder.Entity<MyEntity>()
            .Property((Expression<Func<MyEntity, string>>)propertyExpression)
            .HasColumnName("Fish");
    }
}

这里我构建了MyProperty列的配置,我在lambda表达式中通过名称引用它。

上述代码适用于string属性,但需要进行一些修改才能适用于任何属性类型。对Expression<Func<MyEntity, string>>的强制转换会对属性类型进行硬编码,但我们可以使用动态语言功能消除强制转换。

        var param = Expression.Parameter(typeof(MyEntity));
        dynamic propertyExpression = Expression.Lambda(Expression.Property(param, "MyProperty"), param);

        modelBuilder.Entity<MyEntity>()
            .Property(propertyExpression)
            .HasColumnName("FishFace");