假设我有一些过滤条件通过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对象的情况下,如何实现此多级过滤器的任何想法?
答案 0 :(得分:5)
轻微返工。基本上,我们使用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);
答案 1 :(得分:0)
对于快速查找(在Contains
上使用List
并不是非常快),您可以从过滤器对象创建一个哈希集字典。
字典将为每个客户包含一个项目,该项目中的值将是位置的哈希集合。使用它时,首先检查客户是否在字典中,然后检查该位置是否在该客户的哈希集中:
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
中的项目数。