我是动态表达式查询的新手...
我想动态创建一个联接查询。在它下面的查询是我想要的等效动态查询:
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 query
和整数列表联接后,List<Student>
将包含getAll
条记录。但是结果可以是任何实体列表。列表,即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);
}
注意:我已经安装了System.Linq.Dynamic
nuget软件包版本1.0.7
用于动态linq表达式。
答案 0 :(得分:2)
以下代码对我有用:
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);
}