建立动态LINQ查询的最佳方法是什么? [英] What is the best approach to build dynamic LINQ queries?

查看:57
本文介绍了建立动态LINQ查询的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢那些回答了我上几个问题的人,我得到了下面的代码可以工作,它使您可以将 Where子句集合发送给所有方法附加到LINQ查询.这将适合我需要的情况.

Thanks to those who answered my last couple questions, I got the following code to work which allows you to send a collection of Where clauses to a method which are all attached to a LINQ query. This is going to work for the case at hand that I need.

但是,扩展的最佳方法是什么,以便于:

However, what is the best approach to extend this so that:

    可以发送
  • OrderBy 子句
  • Where子句可以与"OR"逻辑结合使用,而不仅可以与"AND"逻辑
  • 结合使用
  • 其他选项可以动态发送,例如回传的对象中包含哪些字段(例如,在下面的示例中,它不必始终是客户)
  • OrderBy clauses can be sent
  • Where clauses can be combined with "OR" logic and not only with "AND" logic
  • other options can be sent dynamically, e.g. what fields are included in the object sent back (e.g. so that it does not always have to be Customer, in the example below)

基本上,它的背景是能够从此形式的已解析配置文件或用户输入动态构建LINQ查询.

Basically, the background of this is to be able to dynamically build a LINQ query from this form a parsed configuration file or from user input.

该任务使我想起了可以基于参数动态生成SQL语句的类,但是涉及到构建字符串(SQL语句)的类,该类更加简单明了而不是动态构建LINQ查询.

The task reminds me of building classes which could dynamically produce SQL statements based on parameters, but that involved building a string (SQL Statement) which was more straight-forward than dynamically building a LINQ query.

有很多Stackoverflow问题,并且有关此主题的博客文章,但是它们似乎都是针对各个问题的单独解决方案,但是是否有API或库正在逐渐成为构建动态LINQ查询的标准,例如因此我可以轻松采用DSL语法并将其转换为LINQ,例如"FirstName以'a'和(state ='co'或state ='ca')开头"?

There are many Stackoverflow questions and blog posts about this topic, but they each seem to be individual solutions to individual problems, but is there an API or library that is emerging as a standard for building dynamic LINQ queries, e.g. so I can easily take a DSL syntax and translate it into LINQ, e.g. "FirstName startswith 'a' and (state='co' or 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();
        }
    }
}

推荐答案

我当然可以赞同

I can certainly second the suggestion of PredicateBuilder as a useful tool, and is the best way around the OR problem. There is also the Microsoft Dynamic LINQ library which I have used occasionally, and might work with your suggestion of passing clauses from a config file.

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

In most cases when I have needed some element of dynamic querying I have usually ended up coding for particular problems directly much as you have done above. I have a couple of quite complex functions in live systems that start with a basic root query, and then add a number of extra Where and OrderBy clauses dependant on the parameters passed to the function.

尽管大多数LINQ示例似乎都显示了相对简单的查询,但是LINQ库功能非常强大,可以让您逐步建立查询,然后仅在执行时才生成实际查询,因此我倾向于赞成仅使用链式运算符,而不是查询理解语法.

Although most of the LINQ examples seem to show relatively simple queries, the LINQ libraries are pretty powerful allowing you to gradually build up your query step by step, and then only generating the actual query when it is executed, hence I tend to favour just using chained operators rather than the query comprehension syntax.

这篇关于建立动态LINQ查询的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆