简体   繁体   English

如何在C#中使用表达式创建动态lambda连接查询?

[英]How to create dynamic lambda join query using expression in C#?

I am new to dynamic expression query... 我是动态表达式查询的新手......

I want to create a join query dynamically. 我想动态创建一个连接查询。 Below it the query for which I want the equivalent dynamic query: 下面是我想要等效动态查询的查询:

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(); 
  1. The lstNums can be list of any primitive data types lstNums可以是任何原始数据类型的列表
  2. The getAll contains IQuerable, this can be IQuerable of any entity getAll包含IQuerable,这可以是任何实体的IQuerable
  3. The query will contain the List<Student> records after doing join with the getAll and list of integers. 在与getAll和整数列表连接后, query将包含List<Student>记录。 But the result can be any list of entity. 但结果可以是任何实体列表。 The list ie lstNum can be any list of primitive data types. 列表即lstNum可以是任何原始数据类型列表。

Below is what I have tried: 以下是我的尝试:

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));
}

The extension method: 扩展方法:

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);
}

Note: I have installed System.Linq.Dynamic nuget package version 1.0.7 for dynamic linq expression. 注意:我已经为动态linq表达式安装了System.Linq.Dynamic nuget包版本1.0.7

The below code worked for me: 以下代码对我有用:

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)));
}

The extension method is as follows: 扩展方法如下:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM