我有下面的方法为我返回一些数据:
public List<Document> GetDocumentsList(Guid sessionID, bool includeValid, bool includeExpired, bool includeAboutToExpire)
{
using (DB db = new DB())
{
// get the active documents
var docs = db.Documents
.Where(d =>
db.EmployeeStatuses
.Any(s => s.EmpID == d.EmpID && s.StatusEndDate == null && s.Status == "Active")
);
// how to filter the result depending on includeValid, includeExpired and includeAboutToExpired parameters?
return docs.ToList()
}
}这里的问题是,我想根据bool参数过滤结果,例如,如果includeValid为true,则将包括有效文档,如果includeExpired为true,则将包括过期文档,以此类推,我可以将所有三个true或其中一个或两个true。我不希望有多个对DB的调用。有没有一种逻辑可以用一次调用就能做到这一点?
发布于 2013-02-05 00:07:26
LinQ to entities defers execution until the results are enumerated。因此,添加后续.Where()语句不会导致对db的多次调用
var docs = db.Documents
.Where(d =>
db.EmployeeStatuses
.Any(s => s.EmpID == d.EmpID && s.StatusEndDate == null && s.Status == "Active")
);
if (includeValid)
docs = docs.Where(x => [condition]);
//... and so on.
return docs.ToList(); // <- This is where the query is actually executed. 发布于 2013-02-05 00:14:38
您可以使用PredicateBuilder实现。使用这个类,您可以在linq查询上应用一些过滤器。如下所示:
public IEnumerable<Document> GetDocumentsList(Guid? sessionID, bool? includeValid, bool? includeExpired, bool? includeAboutToExpire)
{
var query = db.Documents;
if (sessionID.HasValue)
query = query.And(x => x.SessionID = sessionID.Value);
if (includeValid.HasValue && includeValid.Value)
query = query.And(x => x.IncludeValid = includeValid.Value);
// others parameters...
return query.ToList();
}PredicateBuilder实现
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T> () { return f => true; }
public static Expression<Func<T, bool>> False<T> () { return f => false; }
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
}
}发布于 2013-02-05 00:16:40
看起来你需要连接文档和状态。此外,条件(!includeValid || d.Valid)还为您提供了仅id includeValid为true的有效文档过滤功能
public List<Document> GetDocumentsList(Guid sessionID,
bool includeValid, bool includeExpired, bool includeAboutToExpire)
{
using (DB db = new DB())
{
// get the active documents
var docs = from d in db.Documents
join s in db.EmployeeStatuses on d.EmpID equals s.EmpID
where s.StatusEndDate == null &&
s.Status == "Active" &&
(!includeValid || d.Valid) &&
(!includeExpired || d.Expired) &&
(!includeAboutToExpired || d.AboutToExpired)
select d;
return docs.ToList()
}
}https://stackoverflow.com/questions/14690572
复制相似问题