[英]How to create dynamic lambda join query using expression in C#?
我是動態表達式查詢的新手......
我想動態創建一個連接查詢。 下面是我想要等效動態查詢的查詢:
var lstNums = new List<int> { 100, 101 };
var getAll = new StudenRepository().GetAll(); //Returns IQuerable<Student>
var query = getAll.Join(lstNums, a => a.StudentId, b => b, (a, b) => a).ToList();
lstNums
可以是任何原始數據類型的列表 getAll
包含IQuerable,這可以是任何實體的IQuerable getAll
和整數列表連接后, query
將包含List<Student>
記錄。 但結果可以是任何實體列表。 列表即lstNum可以是任何原始數據類型列表。 以下是我的嘗試:
public static IQueryable JoinQuery(this IQueryable outer, IEnumerable innerEntities, string firstEntityPropName,
Type typeSecondEntity, Type typeResultEntity, params object[] values)
{
LambdaExpression outerSelectorLambda = DynamicLinq.DynamicExpression.ParseLambda(outer.ElementType, null, firstEntityPropName, values);
ParameterExpression expnInput = Expression.Parameter(typeSecondEntity, "inner");
ParameterExpression expnResult = Expression.Parameter(typeResultEntity, "outer");
return outer.Provider.CreateQuery(
Expression.Call(
typeof(Queryable), "Join",
new Type[] { outer.ElementType, innerEntities.AsQueryable().ElementType, outerSelectorLambda.Body.Type, expnResult.Type },
outer.Expression, innerEntities.AsQueryable().Expression, Expression.Quote(outerSelectorLambda), expnInput,
expnResult));
}
擴展方法:
public static IQueryable<T> JoinQuery<T>(this IQueryable outer, IEnumerable innerEntities, string firstEntityPropName, Type typeSecondEntity, Type typeResultEntity, params object[] values)
{
return (IQueryable<T>)Extensions.JoinQuery((IQueryable)outer, (IEnumerable)innerEntities, firstEntityPropName, typeSecondEntity, typeResultEntity, values);
}
注意:我已經為動態linq表達式安裝了System.Linq.Dynamic
nuget包版本1.0.7
。
以下代碼對我有用:
using DynamicLinq = System.Linq.Dynamic;
using LinqExpression = System.Linq.Expressions;
public static IQueryable JoinQuery(this IQueryable outer, IEnumerable innerEntities, string firstEntityPropName,
Type typeSecondEntity, Type typeResultEntity, params object[] values)
{
if (innerEntities == null) throw new ArgumentNullException(nameof(innerEntities));
if (firstEntityPropName == null) throw new ArgumentNullException(nameof(firstEntityPropName));
if (typeSecondEntity == null) throw new ArgumentNullException(nameof(typeSecondEntity));
if (typeResultEntity == null) throw new ArgumentNullException(nameof(typeResultEntity));
LambdaExpression outerSelectorLambda = DynamicLinq.DynamicExpression.ParseLambda(outer.ElementType, null, firstEntityPropName, values);
ParameterExpression expnInput = Expression.Parameter(typeSecondEntity, "inner");
ParameterExpression[] parameters = new ParameterExpression[] {
Expression.Parameter(outer.ElementType, "outer"), Expression.Parameter(innerEntities.AsQueryable().ElementType, "inner")
};
LambdaExpression selectorSecondEntity = DynamicLinq.DynamicExpression.ParseLambda(new ParameterExpression[] { expnInput }, typeSecondEntity, "inner");
LambdaExpression selectorResult = DynamicLinq.DynamicExpression.ParseLambda(parameters, typeResultEntity, "outer");
return outer.Provider.CreateQuery(
Expression.Call(
typeof(Queryable), "Join",
new Type[] { outer.ElementType, innerEntities.AsQueryable().ElementType, outerSelectorLambda.Body.Type, selectorResult.Body.Type },
outer.Expression, innerEntities.AsQueryable().Expression, Expression.Quote(outerSelectorLambda), Expression.Quote(selectorSecondEntity),
Expression.Quote(selectorResult)));
}
擴展方法如下:
public static IQueryable<T> JoinQuery<T>(this IQueryable outer, IEnumerable innerEntities, string firstEntityPropName, Type typeSecondEntity, Type typeResultEntity, params object[] values)
{
return (IQueryable<T>)Extensions.JoinQuery((IQueryable)outer, (IEnumerable)innerEntities, firstEntityPropName, typeSecondEntity, typeResultEntity, values);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.