如何在 C# 中使用表达式创建动态 lambda 连接查询?
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
query
与 getAll
和整数列表进行连接后,将包含 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);
}
我是动态表达式查询的新手...
我想动态创建连接查询。在它下面是我想要等效动态查询的查询:
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,这个可以是任意实体的IQuerablequery
与getAll
和整数列表进行连接后,将包含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);
}