如何使用Type和PropertyInfo

时间:2015-05-30 15:12:49

标签: c# entity-framework reflection

如果我有一个像这样的简单课程

class Person
{
    public int Id { get; set; }
    // ...
}

我想在EF OnModelCreating到Id属性中“做点什么”,例如:

modelBuilder.Entity<Person>().Property( _p => _p.Id ).HasDatabaseGeneratedOption( DatabaseGeneratedOption.None );

我没问题。但是,当我有类型和属性时:

var entityType = typeof(Person);
var propInfo = entityType.GetProperty("Id");

我想要一个像

这样的功能
ModelEntityProperty( modelBuilder, propertyType, entityType).HasDatabaseGeneratedOption( DatabaseGeneratedOption.None );

我的问题:EntityFramework是否允许使用反射信息配置实体/属性?或者它是否专门使用这些LambdaExpressions?

我最后编写了这个函数,但是它很长,而且在我看来比可用的函数更加丑陋:

private PrimitivePropertyConfiguration ModelEntityProperty( 
    DbModelBuilder p_model, 
    PropertyInfo p_propInfo, 
    Type p_entityType = null )
{
    // If the entityType was not set, then use the property's declaring type
    var entityType = (p_entityType == null) ? p_propInfo.DeclaringType : p_entityType;

    // Get the Entity <> method- a generic method
    var genericEntityMethod = typeof( DbModelBuilder ).GetMethod( "Entity", new Type[0] );

    // Get the actual method for the Type we're interested in
    var entityMethod = genericEntityMethod.MakeGenericMethod( new Type[] { entityType } );

    // get the return value of .Entity{p_type}()
    var theEntityConfigurator = entityMethod.Invoke( p_model, new object[0] );


    // I really don't like this, but it works (for now, until they change something)
    var propMethod = theEntityConfigurator
        .GetType()
        .GetMethods( BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public )
        .Where( _mi => _mi.Name == "Property" && _mi.IsGenericMethod )
        .First()
        .MakeGenericMethod( p_propInfo.PropertyType );
    // That whole ugly mess should have been a GetMethod call, but I don't know how
    // to set the parameter type to make sure the correct version of the method is
    // returned unambiguously

    // Build the expression that will be used to identify the property
    var paramExpr = Expression.Parameter( entityType );
    var memberExpr = Expression.MakeMemberAccess( paramExpr, p_propInfo );
    var lambdaExpr = Expression.Lambda( memberExpr, paramExpr );

    // Invoke the correct version of the Property method with the correct parameter
    var thePropertyConfiguration = propMethod.Invoke( 
        theEntityConfigurator, 
        new object[] { lambdaExpr } );

    // and return that thing
    return thePropertyConfiguration as PrimitivePropertyConfiguration;
}

此函数适用于此示例,但它需要更一般的帮助(例如DateTimes等不起作用)。 EF中有“更好或更优雅”的“原生”方式吗?或者这是一个合适的方法,假设它为“Property”方法可以处理的各种ValueTypes修复了吗?

0 个答案:

没有答案