在哪里可以找到使用linq&;lambda表达式生成动态where和orderby sql

本文关键字:表达式 lambda 动态 where sql orderby amp linq 在哪里 | 更新日期: 2023-09-27 18:28:42

在哪里可以找到使用linq&lambda表达式生成动态sql?例如,我需要一种方法来获取这些参数

GoupOperator ('And' or 'OR')
A list of objects each with the following parameters:
    SearchColumn.
    SearchValue.
    SearchOperator (equals, contains, does not equal ...)

以及另一种按任何特定列升序或降序排列的方法

如果这个问题以前得到了正确的回答,我很乐意删除它——我以前看到的答案都不够全面,不足以让一个刚接触linq表达式的人毫不费力地插入现有的应用程序——感谢

在哪里可以找到使用linq&;lambda表达式生成动态where和orderby sql

我在这里的codeproject上发现了几个linq扩展方法(Ilya Builuk编写的通用Where和OrderBy方法,采用列名、搜索值和搜索操作以及分组运算符),展示了如何使用asp.net mvc实现这一点。这些方法构造了一个动态表达式树-非常优雅的解决方案。由于我已经开始使用传统的asmx web服务,我在我的项目中使用了他的助手,并只做了一些更改,使其在这里运行-

以下是的两种方法

public static class LinqExtensions
{
    /// <summary>Orders the sequence by specific column and direction.</summary>
    /// <param name="query">The query.</param>
    /// <param name="sortColumn">The sort column.</param>
    /// <param name="ascending">if set to true [ascending].</param>
    public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string sortColumn, string direction)
    {
        string methodName = string.Format("OrderBy{0}",
            direction.ToLower() == "asc" ? "" : "descending");
        ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
        MemberExpression memberAccess = null;
        foreach (var property in sortColumn.Split('.'))
            memberAccess = MemberExpression.Property
               (memberAccess ?? (parameter as Expression), property);
        LambdaExpression orderByLambda = Expression.Lambda(memberAccess, parameter);
        MethodCallExpression result = Expression.Call(
                  typeof(Queryable),
                  methodName,
                  new[] { query.ElementType, memberAccess.Type },
                  query.Expression,
                  Expression.Quote(orderByLambda));
        return query.Provider.CreateQuery<T>(result);
    }

    public static IQueryable<T> Where<T>(this IQueryable<T> query,
        string column, object value, WhereOperation operation)
    {
        if (string.IsNullOrEmpty(column))
            return query;
        ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
        MemberExpression memberAccess = null;
        foreach (var property in column.Split('.'))
            memberAccess = MemberExpression.Property
               (memberAccess ?? (parameter as Expression), property);
        //change param value type
        //necessary to getting bool from string
        ConstantExpression filter = Expression.Constant
            (
                Convert.ChangeType(value, memberAccess.Type)
            );
        //switch operation
        Expression condition = null;
        LambdaExpression lambda = null;
        switch (operation)
        {
            //equal ==
            case WhereOperation.Equal:
                condition = Expression.Equal(memberAccess, filter);
                lambda = Expression.Lambda(condition, parameter);
                break;
            //not equal !=
            case WhereOperation.NotEqual:
                condition = Expression.NotEqual(memberAccess, filter);
                lambda = Expression.Lambda(condition, parameter);
                break;
            //string.Contains()
            case WhereOperation.Contains:
                condition = Expression.Call(memberAccess,
                    typeof(string).GetMethod("Contains"),
                    Expression.Constant(value));
                lambda = Expression.Lambda(condition, parameter);
                break;
        }

        MethodCallExpression result = Expression.Call(
               typeof(Queryable), "Where",
               new[] { query.ElementType },
               query.Expression,
               lambda);
        return query.Provider.CreateQuery<T>(result);
    }
}

下面是我如何使用这些方法,返回对象只是一个自定义对象,它向客户端网格提供数据

public class Service1 : System.Web.Services.WebService
{
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public JgGrid SearchGrid(int rows, int page, string sidx, string sord,string filters)
    {
        AdvWorksDataContext dc = new AdvWorksDataContext();
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        filters f = serializer.Deserialize<filters>(filters);
        var p = dc.vProductAndDescriptions.AsQueryable();
        if (f.groupOp == "AND")
            foreach (var rule in f.rules)
                p = p.Where<vProductAndDescription>(
                    rule.field, rule.data,
                    (WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op)
                    );
        else
        { 
            //Or
            var temp = (new List<vProductAndDescription>()).AsQueryable();
            foreach (var rule in f.rules)
            {
                var t = p.Where<vProductAndDescription>(
                    rule.field, rule.data,
                    (WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op)
                    );
                temp = temp.Concat<vProductAndDescription>(t);
            }
            p = temp;
        }
        p = p.OrderBy<vProductAndDescription>(sidx, sord);
        return new JgGrid(page, p, rows);
    }
}

对于有许多列需要动态查询组合的情况,我使用dynamic Linq。这是一个以.net 3.5为例编写的库,它说明了如何编写对表达式树进行操作的linq扩展。

它还可以用于根据从客户端接收的字符串组成动态查询,例如列名、排序等。

这是Scott Guthrie发布的一篇文章的链接http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

在本文中,您将找到示例库的链接,该库包含DynamicLinq库的源代码。

在我看来,您正在尝试构建一个linq提供程序。。。请尝试查看本系列教程,了解如何实现自定义的Linq-to-SQL提供程序:Linq:构建IQueryable提供程序系列