0

我需要根据传递给函数的参数查询数据库和过滤器。我正在传递两个日期参数(用作日期范围)、一个名称和一个状态参数。所有参数都可以有“和”或“或”条件。基本上,我想根据填充的参数构建一个 linq 表达式,并将其传递给实体框架以返回结果集。

如何使用最少的“if”语句来做到这一点?如果您能善意地为您的示例代码提供解释,那就太棒了。我正在尝试学习表达式树,因此解释会有所帮助。

在这一点上,我没有太多代码。这就是我在这里发帖的原因。我可以列出方法签名。你到底在找什么?

public enum EmployeeStatus
{
    FullTime,
    PartTime,
    Contract
}

public IEnumerable<Employee> FilterEmployees(DateTime? startDate, 
    DateTime? endDate, string employeeName, EmployeeStatus employeeStatus)
{   }
4

2 回答 2

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;
}
于 2012-11-08T15:53:26.963 回答
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

}

注意 - 这旨在作为伪代码进行演示并且可能有错误 - 请参阅上面的链接以获取正确的实现。

于 2012-11-09T02:13:30.640 回答