我有这个查询。 fromdate,直到参数。
List<TimeEntryReportModel> result = (
from u in ctx.TT_Users
join pm in ctx.TT_ProjectMembers on u.UserID equals pm.UserID
join e in ctx.TT_EntryLogs on pm.UserID equals e.UserID
join p in ctx.TT_Projects on e.ProjectID equals p.ProjectID
where e.EntryDate >= fromdate && e.EntryDate <= until.Value && pm.TT_EntryLogs.Sum(q => q.Duration) > 0
select new TimeEntryReportModel
{
UserId = e.UserID,
DisplayName = u.DisplayName,
UnitId = u.TT_BusinessUnits.UnitId,
//select many more property's here that I get from e, p, pm, u etc.
}
).Distinct().OrderBy(n => n.DisplayName).ToList();
在我的3个控制器方法中,我想从这个结果中访问一些对象。例如:在一个方法中,我希望拥有所有TimeEntryReportModel对象,其中用户id是特定值。
所以方法看起来像这样(其中userId是方法中的参数):
return result.Where(e => e.UserId == userId).ToList();
另一种方法如下:
return result.Where(l => l.UnitId == unitId).ToList();
这非常有用,但是因为结果包含大约420个TimeEntryReportModel,而在其他方法中我必须对该结果进行子查询,所以在我实际收到所需数据之前大约需要10秒。
解决此问题的一种方法是复制并粘贴查询3次,并将必要的where where条件添加到每个查询中。但这看起来很狡猾,因为我基本上只是针对一个条件重写整个查询...我不能根据传递给包含此查询的方法的参数为查询添加条件吗?
tl; dr 是否可以根据参数向LINQ查询添加条件?
答案 0 :(得分:1)
排序,您可以使用逻辑OR来获得相同的效果。例如,让我们说我有一个日期参数,日期是可选的,查询总是检查一个id。你可以像这样构建你的Where调用:
from u in ctx.TT_Users
where u.userId >= 1001
&& (myDateParam == null || u.RegisteredOn >= myDateParam);
如果指定了myDateParam,则where返回在指定日期之后注册的ID大于1001的所有用户。显然,我的例子是虚构的......这个原则可能对你有所帮助。如果未指定myDateParam,则返回所有ID大于1001的用户。
当然,短路是使这成为可能的原因。您也可以使用布尔值和列表等来执行此操作。
答案 1 :(得分:1)
在构造变量.ToList()
时使用result
函数会导致执行查询。将结果视为类型IQueryable<TimeEntryReportModel>
的变量而不是列表,请求将在稍后执行(在控制器方法中调用.ToList()
时)。
所以,你可以写:
IQueryable<TimeEntryReportModel> result = (
...
).Distinct().OrderBy(n => n.DisplayName);
稍后(在相同或其他函数中),通过添加where子句指定查询:
...
var specifiedResult = result.Where(e => e.UserId == userId).ToList();
在我看来,延迟执行是LINQ的主要利益之一。