构建动态LINQ查询的最佳方法是什么?

时间:2009-11-23 11:30:41

标签: c# linq

感谢那些回答了我最后几个问题的人,我得到了以下代码,它允许您向一个方法发送 Where子句的集合附加到LINQ查询。这对我需要的手头情况有用。

然而,扩展的最佳方法是什么,以便:

  • 订单条款可以发送
  • where子句可以与“OR”逻辑组合,而不仅仅与“AND”逻辑组合
  • 可以动态发送其他选项,例如发回的对象中包含哪些字段(例如,在下面的示例中,它并不总是客户)

基本上,这样做的背景是能够从这个表单动态构建一个LINQ查询解析配置文件或用户输入。

该任务提醒我构建可以根据参数动态生成SQL语句的类,但这涉及构建字符串(SQL语句),这更直接而不是动态构建LINQ查询。

有很多关于此主题的Stackoverflow问题和blog posts,但它们似乎都是针对个别问题的单独解决方案,但是有一个API或库正在成为构建动态LINQ查询的标准,例如: 所以我可以轻松地采用DSL语法并将其转换为LINQ,例如“FirstName以'a'开头,(state ='co'或state ='ca')”?

using System;
using System.Collections.Generic;
using System.Linq;

namespace TestDynamicLinq2343
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<Customer> customers = Customer.GetCustomers();

            List<Func<Customer, bool>> whereClauses = new List<Func<Customer, bool>>();
            whereClauses.Add(c => c.LastName.ToUpper().Contains("A"));
            whereClauses.Add(c => c.FirstName.ToUpper().Contains("O"));
            whereClauses.Add(c => c.FirstName.ToUpper().Contains("E"));

            foreach (var customer in Customer.GetFilteredCustomers(customers, whereClauses))
            {
                Console.WriteLine(customer.LastName);
            }

            Console.ReadLine();
        }
    }

    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Street { get; set; }
        public string Location { get; set; }
        public string ZipCode { get; set; }

        public static List<Customer> GetCustomers()
        {
            List<Customer> customers = new List<Customer>();
            customers.Add(new Customer { FirstName = "Jim", LastName = "Jones" });
            customers.Add(new Customer { FirstName = "Joe", LastName = "Adams" });
            customers.Add(new Customer { FirstName = "Jake", LastName = "Johnson" });
            customers.Add(new Customer { FirstName = "Angie", LastName = "Reckar" });
            customers.Add(new Customer { FirstName = "Jean", LastName = "Anderson" });
            return customers;
        }

        public static List<Customer> GetFilteredCustomers(List<Customer> customers, List<Func<Customer, bool>> whereClauses)
        {
            IEnumerable<Customer> dbCustomers = customers;
            foreach (var whereClause in whereClauses)
            {
                dbCustomers = dbCustomers.Where(whereClause);
            }
            return dbCustomers.ToList();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

动态查询构建是某种单调乏味的任务。请拜访 PredicateBuilder。您可以深入了解动态quire的构建方式。

答案 1 :(得分:0)

我当然可以将PredicateBuilder的建议作为一种有用的工具,并且是解决 OR 问题的最佳方法。我偶尔也会使用Microsoft Dynamic LINQ library,并且可能与你在配置文件中传递子句的建议有关。

在大多数情况下,当我需要一些动态查询元素时,我通常会直接编写特定问题的代码,就像你上面所做的那样。我在实时系统中有一些非常复杂的函数,它们以基本的根查询开头,然后根据传递给函数的参数添加一些额外的WhereOrderBy子句。

虽然大多数LINQ示例似乎都显示相对简单的查询,但LINQ库非常强大,允许您逐步构建查询,然后仅在执行时生成实际查询,因此我倾向于赞成使用链式运算符而不是查询理解语法。