简体   繁体   English

过滤条件使用LINQ进行搜索

[英]Filter Criteria Search using LINQ

I am 'newer' to LINQ queries have another one of those questions where I have something going but not sure if this is the most effective way to go about it. 我对LINQ查询“更新”有另外一个问题,我有什么事情要发生但不确定这是否是最有效的方法。 In my project, I am working in a real DB, but for a sake of simplicity, here I will condense it down to a simple list of employees: 在我的项目中,我在一个真正的数据库中工作,但为了简单起见,我将把它简化为一个简单的员工列表:

var employees = new List<Employee>
        {
            new Employee { Id = 0, firstName = "James", LastName = "Bond", Manager = "M", StartDate = DateTime.Now },
            new Employee { Id = 1, firstName = "Eric", LastName = "Bond", Manager = "M", StartDate = DateTime.Now },
            new Employee { Id = 2, firstName = "Sue", LastName = "Milton", Manager = "Q", StartDate = DateTime.Now },
            new Employee { Id = 3, firstName = "Olivia", LastName = "Milton", Manager = "M", StartDate = DateTime.Now },
            new Employee { Id = 4, firstName = "Alice", LastName = "Raymond", Manager = "M", StartDate = DateTime.Now },
            new Employee { Id = 5, firstName = "James", LastName = "Skywalker", Manager = "M", StartDate = DateTime.Now },
            new Employee { Id = 6, firstName = "Luke", LastName = "Skywalker", Manager = "M", StartDate = DateTime.Now },

        };

I have to search in this list based on given criteria.. where criteria is combination of various fields with OR and AND operations with in the fields for example get me all employees where: 我必须根据给定的标准在此列表中进行搜索..其中,条件是各种字段与OR的组合以及在字段中的AND操作,例如,让我所有员工在哪里:

  • firstName = "James" OR "eric" AND manager = "Q" firstName =“James” “eric” AND manager =“Q”
  • lastname = "bond" OR "Martha" lastname =“bond” “Martha”
  • firstName = "James" AND Lastname = "Bond" and so on... firstName =“James” AND Lastname =“Bond”等等......

This is going to be a web API call and I have to do this in one method. 这将是一个Web API调用,我必须在一个方法中执行此操作。 The other challenge is that each search parameter is 'optional" ie , they can pass me a list of firstnames and a manager name and ignore the last names parameters etc. So here is what I started coded: 另一个挑战是每个搜索参数都是“可选的”,即,他们可以传递一个名字和管理员名称的列表,并忽略姓氏参数等。所以这是我开始编码的:

    public IList<Employee> GetFilteredEmployees(IList<String> firstnames = null,
                                                IList<String> lastnames = null,
                                                IList<String> managers = null)
    {
    if (firstnames != null && firstnames.Any())
     {
          foreach (var fn in firstnames)
          {
             employeeByFn = employees.Where(emp => emp.firstName == fn).ToList<Employee>();
          }

      }

     if (lastnames != null && lastnames.Any())
     {
         foreach (var ln in lastnames)
         {
             employeeByLn = employees.Where(emp => emp.LastName == ln).ToList<Employee>();
         }
      }

     ..... // code ellided
    }

As you can see, this is getting ugly even with a few search criteria parameters. 正如您所看到的,即使使用一些搜索条件参数,这也会变得很难看。 In my real project, I have up to 16 of those. 在我的真实项目中,我有多达16个。 Also at the end of all these sub-queries, I have to merge my results into one employee list and return that keeping in mind that any of the sub-query result may be null. 同样在所有这些子查询的最后,我必须将我的结果合并到一个员工列表中并返回,请记住任何子查询结果可能为空。

I am sure this is not a unique problem and I see similar questions asked before but not exactly the same problem. 我确信这不是一个独特的问题,我看到之前提出的类似问题,但不是完全相同的问题。 What would be elegant way of doing this that is also easy to maintain .ie if they decide to add more search criteria later (say by start Date), I want to be able to easily modify my method to handle that. 这样做的优雅方式也很容易维护。如果他们决定稍后添加更多搜索条件(比如开始日期),我希望能够轻松修改我的方法来处理它。

Thanks a bunch for looking. 非常感谢一群人。

You can keep on adding Where() conditions on the same result instead of creating many partial results. 您可以继续在同一结果上添加Where()条件,而不是创建许多部分结果。

public IList<Employee> GetFilteredEmployees(IList<String> firstnames = null,
                                            IList<String> lastnames = null,
                                            IList<String> managers = null)
{
    IQueryable<Employee> result = employees;

    if (firstnames != null)
        result = result.Where(emp => firstnames.Contains(emp.firstName));

    if (lastnames != null)
        result = result.Where(emp => lastnames.Contains(emp.LastName));

    if (managers != null)
        result = result.Where(emp => managers.Contains(emp.Manager));

    ... // code ellided

    return result.ToList();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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