I'm looking to create a Linq Where, based on a nested property.
Let's say this is my project:
public class Car {
public Engine Engine { get; set; }
}
public class Engine {
public int HorsePower { get; set; }
}
var myCar = new Car() {
Engine = new Engine() {
HorsePower = 400
}
};
I use this code found somewhere, which allow to create Expression,
private Expression<Func<TItem, bool>> PropertyEquals<TItem, TValue>( PropertyInfo property, TValue value ) {
var param = Expression.Parameter( typeof( TItem ) );
var memberExp = Expression.Property( param, property );
BinaryExpression body;
//If nullable, Expression.Equal won't work even if the value is not null. So we convert to non nullable (the compared expression)
Type typeIfNullable = Nullable.GetUnderlyingType( memberExp.Type );
if ( typeIfNullable != null ) {
var convertedExp = Expression.Convert( memberExp, Expression.Constant( value ).Type );
body = Expression.Equal( convertedExp, Expression.Constant( value ) );
} else {
body = Expression.Equal( memberExp, Expression.Constant( value ) );
}
return Expression.Lambda<Func<TItem, bool>>( body, param );
}
Now, I had like to have an equivalent, calling my method PropertyEquals
var engine = myCar.Select( c => c.Engine.HorsePower == 400 );
Something like
var property = GetPropertyForDotSequence( typeof( Car ), "Engine.HorsePower" );
.Select( PropertyEquals<TEntity, int>( property , 400 ) );
I found a method which allow to find property based on a dotted format (GetPropertyForDotSequence), which work properly, but return HorsePower property info, and not Engine.HorsePower, so I get an error saying Car doesnot have an int32 property called HorsePower.
private PropertyInfo GetPropertyForDotSequence ( Type baseType, string propertyName ) {
var parts = propertyName.Split( '.' );
return ( parts.Length > 1 )
? GetPropertyForDotSequence( baseType.GetProperty( parts[ 0 ] ).PropertyType, parts.Skip( 1 ).Aggregate( ( a, i ) => a + "." + i ) )
: baseType.GetProperty( propertyName );
}
Aucun commentaire:
Enregistrer un commentaire