繁体   English   中英

使用Linq过滤多级where子句

[英]Multiple level where clause filtering with Linq

假设我有一些过滤条件通过CustomerFilter对象数组传递到我的应用程序中,我需要运行查询并根据从Linq到Entities查询的过滤器返回结果。

因此,在这种情况下,客户将通过服务调用将一组CustomerFilter对象传递给我。

过滤对象:

class CustomerFilter
{
    public string CustomerID;
    public int[] LocationID;
}

示例数据:

CustomerID    LocationID 

1             1

              2

              3

              4 

2             2 

              3 


              4

我可以很容易地在外部CustomerID上构建查询过滤,如下所示。

查询:

    public void GetCustomerResults(List<CustomerFilter> accounts)
    {
        List<string> customer = (from a in accounts select a.CustomerID).ToList();

        var locations = ctx.Portal_SurveyLocations
                            .Where(w => customer.Contains(w.CustNum))
                            .OrderBy(o => o.LocationKey);
    }

所以我可以按外部标准进行筛选,但我不确定如何根据每个CustomerID的多个位置ID进行筛选。 显然只是放置一个OR子句会产生不正确的结果,因为它会引入具有匹配LocationID的其他CustomerID。

在传入CustomerFilter对象的情况下,如何实现此多级过滤器的任何想法?

轻微返工。 基本上,我们使用Any的组合来遍历子集合以实现期望的结果。

var locations = ctx.Portal_SurveyLocations
    .Where(w => accounts.Any(a => a.CustomerID == w.CustNum &&
                                  a.LocationID.Any(l => w.LocationKey == l)))
    .OrderBy(o => o.LocationKey);

对于快速查找(使用List上的Contains不是很快),您可以从过滤器对象创建哈希集的字典。

字典将为每个客户包含一个项目,该项目中的值将是位置的哈希集合。 使用它时,首先检查客户是否在字典中,然后检查该位置是否在该客户的哈希集中:

public void GetCustomerResults(List<CustomerFilter> accounts) {
  Dictionary<string, HashSet<int>> lookup =
    accounts.ToDictionary(a => a.CustomerID, a => new HashSet<int>(a.LocationID));

    var locations =
      ctx.Portal_SurveyLocations
      .Where(w =>
        lookup.ContainsKey(w.CustNum) &&
        lookup[w.CustNum].Contains(w.LocationKey))
      .OrderBy(o => o.LocationKey);
}

字典和散列集都具有查找项目的O(1)复杂度,因此整个操作获得O(n+m)复杂度,其中n是过滤器的数量, m是项目的数量Portal_SurveyLocations

暂无
暂无

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

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