[英]I can dynamically create an Expression<Func<T, bool>> predicate ,but how do i create Expression<Func<T1,T2,bool>>
[英]How can I do a Func<object[],Expression<Func<T,bool>>> dynamic?
我正在做一個.Find(objects [] keys)方法,它動態創建一個lambda函數來查詢數據庫。
基本上我想要的是:
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,這意味着它不會在數據庫端執行。
您需要使用Expression.Constant
方法而不是Expression.ArrayIndex
,因為您將無法使用FirstOrDefault
方法使用鍵值傳遞到表達式數組。
private static LambdaExpression CreateKeyExpression(Type C1Type, object[] parameters)
{
var instanceParameter = Expression.Parameter(C1Type);
PropertyInfo[] objectKeys = C1Type.GetKeyProperties().ToArray();
var expr = Expression.Equal(Expression.Property(instanceParameter, objectKeys[0]),
Expression.Constant(parameters[0], objectKeys[0].PropertyType));
for (int i = 1; i < objectKeys.Length; i++)
{
expr = Expression.AndAlso(expr, Expression.Equal(
Expression.Property(instanceParameter, objectKeys[i]),
Expression.Constant(parameters[i], objectKeys[i].PropertyType)));
}
return Expression.Lambda(expr, instanceParameter);
}
var parameters = new object[] { Guid.NewGuid(), Guid.NewGuid() };
var lambdaExpression = CreateKeyExpression(typeof(TestClass), parameters);
var testClasses = new List<TestClass>() { new TestClass { Id = (Guid)parameters[0], Id1 = (Guid)parameters[1] } };
var testClass = testClasses.AsQueryable().FirstOrDefault((Expression<Func<TestClass, bool>>)lambdaExpression);
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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.