If I had a simple class like this
class Person
{
public int Id { get; set; }
// ...
}
and I wanted "do something" in EF OnModelCreating to the Id property, such as:
modelBuilder.Entity<Person>().Property( _p => _p.Id ).HasDatabaseGeneratedOption( DatabaseGeneratedOption.None );
I have no problem. However, when I have the Type and Property:
var entityType = typeof(Person);
var propInfo = entityType.GetProperty("Id");
I want a function such as
ModelEntityProperty( modelBuilder, propertyType, entityType).HasDatabaseGeneratedOption( DatabaseGeneratedOption.None );
My question: Does EntityFramework allow one to configure entities/properties using reflection information? Or is it exclusively using these LambdaExpressions?
I ended up writing this function, but it is long and in my opinion much uglier than what may be available:
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;
}
This function works perfectly for this example, but it needs help to be more general (e.g. DateTimes, etc. don't work). Is there a better or more elegant way of doing this "natively" within EF? Or is this an appropriate method, assuming its fixed for the various ValueTypes that the "Property" method can handle?
Aucun commentaire:
Enregistrer un commentaire