如何动态构建Linq查询



我看到了一些旧的帖子,但不知道如何实现这一点,请帮助一个例子。

我正在一个数据表上运行一个查询来分组所有的列。数字列将只在运行时被知道,因此我需要动态地构建查询。

var newGroup = from row in dataTable.AsEnumerable() 
group row by new { ID = row.Field<string>("column1"), group1 = row.Field<string>("column2") };

我需要动态地为n number of columns构建上述查询。

请解释如何通过循环遍历列列表来构建ParameterExpression并构建Lambda表达式。

总之:有不同的方法来实现这一点。困难的方法是通过使用表达式来构建Func和Predicates的组合。更简单的方法是利用下面提到的库- LINQ Dynamic Query Library:

解决方案# 1:这是一个很好的起点-在c#中运行时构建LINQ查询

解决方案# 2:您也应该能够通过使用Linq Dynamic Query来做到这一点,因为它是为此目的而构建的-动态LINQ(第1部分:使用LINQ动态查询库)

我已经看到这个问题很多次了,所以我决定创建一个博客,而不是从c#操作数据。通过使用动态SQL,我已经完成了SQL数据库级别的繁重工作。

这是链接。

我有一个情况,我需要动态地为查询的左侧和右侧生成一个LINQ查询。换句话说,Where("some property == some value")。我使用了LINQPad上的PredicateBuilder,并尝试了其他一些东西,但最终LINQ动态查询库(System.Linq.Dynamic)使这项任务变得非常简单。

在不讨论所有细节的情况下,我所拥有的是一个方法,该方法接受参数,用于在MVC页面上筛选和排序jqGrid上的项。一个名为QueryOptions的对象保存了各种查询设置。数据。ImportDataSearchView是绑定到后台数据库视图的实体框架实体。

通过调用

构建过滤器表达式:
        options.FilterExpression += filterList.BuildFilterExpression<Data.ImportDataSearchView>();

BuildFilterExpression部分如下:

    public string BuildFilterExpression<T>()
    {
        var type = typeof(T);
        var exp = string.Empty;
        foreach (Filter filter in this)
        {
            var typeName = filter.DataType.ToLower();
            // Skip if no values
            if (!filter.Values.Any())
                continue;
            switch (typeName)
            {
                case "string":
                    // html decode string and escape single quotes
                    var stringVal = System.Web.HttpUtility.HtmlDecode(filter.Values[0]);
                    stringVal = stringVal.Replace("'", "''");
                    if (filter.Operator == Enums.FilterOperator.CONTAINS)
                        exp += string.Format("{0}.Trim().ToLower().Contains("{1}")", filter.Attribute, stringVal.Trim().ToLower());
                    else if (filter.Operator == Enums.FilterOperator.DOES_NOT_EQUAL)
                        exp += string.Format("!{0}.ToLower().Equals("{1}")", filter.Attribute, stringVal.ToLower());
                    else if (filter.Operator == Enums.FilterOperator.DOES_NOT_CONTAIN)
                        exp += string.Format("!{0}.Trim().ToLower().Contains("{1}")", filter.Attribute, stringVal.Trim().ToLower());
                    else if (filter.Operator == Enums.FilterOperator.ENDS_WITH)
                        exp += string.Format("{0}.Trim().ToLower().EndsWith("{1}")", filter.Attribute, stringVal.Trim().ToLower());
                    else if (filter.Operator == Enums.FilterOperator.EQUALS)
                        exp += string.Format("{0}.ToLower().Equals("{1}")", filter.Attribute, stringVal.ToLower());
                    else if (filter.Operator == Enums.FilterOperator.STARTS_WITH)
                        exp += string.Format("{0}.Trim().ToLower().StartsWith("{1}")", filter.Attribute, stringVal.Trim().ToLower());
                    break;
                //case "select": -- for dropdowns
                //case "datetime": -- for dates, etc. etc.
            // add spaces around expression
            exp = string.Format(" {0} ", exp);
            // add and/or to expression
            if (this.IndexOf(filter) != this.Count() - 1)
                exp += string.Format(" {0} ", ExpressionType.ToLower() == "and" ? "&&" : "||");
        }
        return exp;
    }

然后按如下方式检索数据,在构建表达式字符串之后:

        options.OrderBy = string.IsNullOrEmpty(sortIndex) ? "TrackingId asc" : string.Format(" {0} {1} ", sortIndex, sortOrder);
        var db = new Data.BmpDB();
        var list = string.IsNullOrEmpty(options.FilterExpression)
            ? db.ImportDataSearchViews.OrderBy(options.OrderBy).ToList()
            : db.ImportDataSearchViews.Where(options.FilterExpression).OrderBy(options.OrderBy).ToList();

选项。下面的FilterExpression字符串是由BuildFilterExpression方法将三个搜索条件字段拼凑成一个漂亮的、简单的LINQ where子句谓词字符串的示例:

" BmpName.Trim () .ToLower () .Contains("作物"),,DataProviderId.ToLower () .Equals("123 "),,StatusId == 1"

相关内容

  • 没有找到相关文章

最新更新