5

データベースを照会するラムダ関数を動的に作成する .Find(objects[] keys) メソッドの実行に取り組んでいます。

基本的に私が欲しいのは:

var mykeys = new Guid("37ec1659-b35e-46c9-a7fc-e9802644ca1a");
IQueryable<T> database ;
Func<object[],Expression<Func<T,bool>>> objectFinder = CreateKeyExpression(typeof(T));
var foundObject = database.FirstOrDefault(objectFinder(mykeys));

private LambdaExpression CreateKeyExpression(Type C1Type)
{

    ParameterExpression instanceParameter = Expression.Parameter(C1Type);
    ParameterExpression keyParameters = Expression.Parameter(typeof(object[]));

    PropertyInfo[] objectKeys = C1Type.GetKeyProperties().ToArray();
    var expr = Expression.Equal( Expression.TypeAs( Expression.Property(instanceParameter,objectKeys[0]),typeof(object)),
      Expression.ArrayIndex(keyParameters,Expression.Constant(0))); 


    for (int i = 1; i < objectKeys.Length; i++)
    {
        expr = Expression.AndAlso(expr, Expression.Equal(
            Expression.Property(instanceParameter,objectKeys[i]),
            Expression.ArrayIndex(keyParameters,Expression.Constant(i))
            )); 

    }

    var lmp= Expression.Lambda(expr, instanceParameter);

    return Expression.Lambda(lmp, keyParameters);
}

これを達成する方法についてのアイデアはありますか? 上記Func<object[],Func<T,bool>>により、 IQueryable が IEnumerable になります。つまり、データベース側では実行されません。

4

2 に答える 2

0
private Expression<Func<object[], Expression<Func<C1Source, bool>>>> CreateKeyExpression<C1Source>()
{

    ParameterExpression instanceParameter = Expression.Parameter(typeof(C1Source));
    ParameterExpression keyParameters = Expression.Parameter(typeof(object[]));

    PropertyInfo[] objectKeys = typeof(C1Source).GetKeyProperties().ToArray();
    var expr = Expression.Equal( Expression.Property(instanceParameter,objectKeys[0]),
     Expression.Convert( 
        Expression.ArrayIndex(keyParameters,Expression.Constant(0)),
        objectKeys[0].PropertyType)
        ); 

    for (int i = 1; i < objectKeys.Length; i++)
    {
        expr = Expression.AndAlso(expr, Expression.Equal(
            Expression.Property(instanceParameter,objectKeys[i]),
            Expression.Convert(
                Expression.ArrayIndex(keyParameters,Expression.Constant(i)),
                objectKeys[i].PropertyType)
                ); 

    }

    var lmp= Expression.Lambda(expr, instanceParameter);

    return Expression.Lambda<Func<object[], Expression<Func<C1Source, bool>>>>(lmp, keyParameters);

}
于 2013-08-10T17:03:01.940 に答える