我有一个适用于我的搜索结果的过滤器。
我现在拥有以下内容:
Filter 1 = Any
Filter 2 = Atlas
Filter 3 = phoenix
现在当过滤器在任何上时,我运行以下查询:
foreach (DetectorStatu status in loadOperation.Entities.OrderBy(d => d.Status).Take(25).Reverse())
当过滤器处于 Atlas :
时foreach (DetectorStatu status in loadOperation.Entities.OrderBy(d => d.Status).Where(d => ((d as DetectorStatu).Detector as Detector).EnabledDetectorTypes.Count(t => t.DetectorTypeID == 1) > 0).Take(25).Reverse())
当过滤器在 Phoenix 上时:
foreach (DetectorStatu status in loadOperation.Entities.OrderBy(d => d.Status).Where(d => ((d as DetectorStatu).Detector as Detector).EnabledDetectorTypes.Count(t => t.DetectorTypeID == 2 || t.DetectorTypeID == 3) > 0).Take(25).Reverse())
他们正在调用的实际查询:
[Query]
[OutputCache(OutputCacheLocation.Server, 60)]
public IQueryable<DetectorStatu> GetDetectorDatabacklog(int userID)
{
User user = ObjectContext.Users
.Include("TeamMemberships")
.First(u => u.UserID == userID);
var teamIDs = user.TeamMemberships.Select(t => t.TeamID).ToList();
var siteIDs = ObjectContext.SiteMemberships.Where(t => teamIDs.Contains(t.TeamID)).Select(t => t.SiteID).ToList();
var DetectorStatus = ObjectContext.DetectorStatus
.Include("Detector")
.Include("Detector.Track")
.Include("Detector.Site")
.Include("Detector.EnabledDetectorTypes")
.Include("Detector.EnabledDetectorTypes.DetectorType")
.Where(d => siteIDs.Contains(d.Detector.SiteID))
.OrderBy(d => d.Status);
return DetectorStatus;
}
现在我的问题:
有没有办法让这种动态/更短?
现在我通过if语句检查过滤器,然后运行所有代码。 但是,我想再添加8个过滤器。并且如果声明会使代码变得非常大且非常不清楚,那么再增加8个 我基本上添加了50行代码,而我只需要更改1行查询。
答案 0 :(得分:4)
您可以通过多个步骤构建查询:
IQueryable<DetectorStatu> query = loadOperation.Entities.OrderBy(d => d.Status);
然后根据您的设置添加过滤器:
if (<filter is Atlas>)
{
query = query.Where(d => ((d as DetectorStatu).Detector as Detector).EnabledDetectorTypes.Count(t => t.DetectorTypeID == 1) > 0);
}
else if (<filter is Phoenix>)
{
query = query.Where(d => ((d as DetectorStatu).Detector as Detector).EnabledDetectorTypes.Count(t => t.DetectorTypeID == 2 || t.DetectorTypeID == 3) > 0);
}
等等。当然,您必须用<filter is ...>
替换正确的代码。
最后你只有一个 foreach语句:
query = query.Take(25).Reverse();
foreach (DetectorStatu status in query) { ... }
在您输入foreach
时,只会向数据库发送一个查询。这将考虑从“OrderBy”到“Reverse”的所有步骤。
答案 1 :(得分:2)
可以定义System.Linq.Expression:
Expression<Func<DetectorStatu, bool>> filter = null;
if(any){
filter = x => true;
}
if(Atlas){
filter = d => ((d as DetectorStatu).Detector as Detector).EnabledDetectorTypes.Count(t => t.DetectorTypeID == 1) > 0
}
if(Phoenix){
filter = d => ((d as DetectorStatu).Detector as Detector).EnabledDetectorTypes.Count(t => t.DetectorTypeID == 2 || t.DetectorTypeID == 3) > 0;
}
最后:
foreach (DetectorStatu status in loadOperation.Entities.OrderBy(d => d.Status)
.Where(filter)
.Take(25).Reverse())
答案 2 :(得分:0)
Where
子句只需要一个谓词(一个返回bool的Func),你可以将它作为参数传递给你的函数。所以基本上你可以为每个&#34; Filter&#34;传递不同的谓词。选项并将其应用于您的IQueryable Where
子句