我需要根据传递给函数的参数查询数据库和过滤器。我传递了两个日期参数(用作日期范围),名称和状态参数。所有参数都可以有'和'或'或'条件。基本上,我想根据填充的参数构建一个linq表达式,并将其传递给Entity Framework以返回结果集。
如何使用最少的“if”语句执行此操作?如果您能够对您的示例代码提供解释,那将是非常棒的。我正在尝试学习表达树,所以解释会有所帮助。
此时我的代码不多。这就是我在这里发布的原因。我可以列出方法签名。你到底在想什么?
public enum EmployeeStatus
{
FullTime,
PartTime,
Contract
}
public IEnumerable<Employee> FilterEmployees(DateTime? startDate,
DateTime? endDate, string employeeName, EmployeeStatus employeeStatus)
{ }
答案 0 :(得分:4)
public IQueryable<Employee> FilterEmployees(IQueryable<Employee> query, DateTime? startDate, DateTime? endDate, string employeeName, EmployeeStatus employeeStatus)
{
if (startDate != null)
query = query.Where(x => x.StartDate >= startDate);
// etc...
return query;
}
答案 1 :(得分:2)
所有参数都可以包含'和'或'或'条件。 - 您可以考虑使用PredicateBuilder。见http://www.albahari.com/nutshell/predicatebuilder.aspx。为什么?因为这允许您编写单个查询,但仅在需要时才添加AND / OR谓词。您可能需要也可能不需要此功能,但这是一个很好的功能。在实际调用查询之前没有数据库开销 - 它提供了一种有条件地构建IQueryable的方法,您可能不希望在某些条件下匹配字段。例如。前几天我用这个来忽略产品代码字段 - 最小长度为10 - 在输入字符串少于10个字符的搜索中。
这将允许您使用if条件添加AND / OR语句,如下所示:
public IQueryable<Employee> FilterEmployees(IQueryable<Employee> query, DateTime startDate, DateTime endDate, string employeeName, EmployeeStatus employeeStatus)
{
var predicate = PredicateBuilder.True<Employee>();
//All names starting with 'A'
predicate = predicate.And(x => x.Name.StartsWith("A"));
//Add a condition only if the employee is PartTime
if (employeeStatus == EmployeeStatus.PartTime)
{
//Add condition for when they start
predicate = predicate.And(x => x.StartDate >= startDate);
}
else
{
//Say we don't care about the start date for the other employee statuses,
//but we want to add condition for when non-part-time employees are due to leave
predicate = predicate.And(x => x.EndDate <= endDate);
//or their name ends in 'z'
predicate = predicate.Or(x => x.Name.EndsWith("z"));
}
IQueryable<Employee> employees = query.FindBy(predicate); //you should probably use a repository here to return your query
return employees
}
注意 - 这是伪造的代码,用于演示并可能有错误 - 请参阅上面的链接以了解正确的实现。