LINQ-如何在哪里忽略空列表

时间:2019-09-05 12:32:15

标签: c# .net linq .net-core

这些是我使用LINQ的第一步。我有两个过滤器列表作为参数,也可以为空。如果以这种方式执行代码,则不会从空列表中获取任何值。
如果要忽略空列表,代码应该是什么样的?

    public List<PersonDTO> GetPersons(int pageNumber, int pageSize, List<string> departments, List<string> locations, string filterText)
    {
        if (filterText == null)
        {
            filterText = "";
        }

        List<Person> personsList = _dbContext.Persons
            .Where(a => (a.firstName.ToLower().Contains(filterText.ToLower()) || a.lastName.ToLower().Contains(filterText.ToLower()))
                        && departments.Contains(a.department) 
                        && locations.Contains(a.location))
            .Skip(pageNumber * pageSize).Take(pageSize).ToList();

        return _mapper.Map<List<PersonDTO>>(personsList);
    }

8 个答案:

答案 0 :(得分:4)

使用if处理不在查询中为空的情况:

IEnumerable<Person> persons = _dbContext.Persons;
if(!string.IsNullOrEmpty(filterText))
{
    string lowerFilterText = filterText.ToLower();
    persons = persons
       .Where(p => p.firstName.ToLower().Contains(lowerFilterText) || a.lastName.ToLower().Contains(lowerFilterText));
}
if(departments.Any())
{
    persons = persons.Where(p => departments.Contains(p.department));
}
if(locations.Any())
{
    persons = persons.Where(p => locations.Contains(p.location));
}
List<Person> personList = persons.Skip(pageNumber * pageSize).Take(pageSize).ToList();

由于LINQ的执行延迟,因此将仅在最终ToList处执行一次最终查询。

答案 1 :(得分:0)

看看否Any()是否可以帮助您。 示例:

string[] arr = new string[10] {"a","b","c","d","e","f","g","h","i","j"};
List<string> vowels = new List<string>() {"a","e","i","o","u"};
List<string> empty = new List<string>();

arr.Where(letter => vowels.Contains(letter)); 
//yields "a","e","i"
arr.Where(letter => (!empty.Any() || empty.Contains(letter))); 
//yields "a","b","c","d","e","f","g","h","i","j"

在您的示例之后,我将链接.Where()表达式,而不是将它们全部放入一个大的单个表达式中。

答案 2 :(得分:0)

您需要将列表包装在括号中,并使用计数验证使其对于每个列表都是可选的,就像这样:

List<Person> personsList = _dbContext.Persons
    .Where(a => 
        (a.firstName.ToLower().Contains(filterText.ToLower()) || 
        a.lastName.ToLower().Contains(filterText.ToLower())) && 
        (departments.Count == 0 || departments.Contains(a.department)) && 
        (locations.Count == 0 || locations.Contains(a.location)))
    .Skip(pageNumber * pageSize)
    .Take(pageSize)
    .ToList();

通过这种方式,您可以将条件数组转换为可选状态,因此只要数组!(list.Count == 0)中有一个项目,它就会尝试评估过滤器。

答案 3 :(得分:0)

您需要这样的东西:

Why would you use Expression> rather than Func?

Expression<Func<Persons, bool>> expresionFinal = c => c.Active;

    if (departments.Any())
                {
                    Expression<Func<Persons, bool>> expresionDepartments = c => departments.Contains(p.department);
                    expresionFinal = PredicateBuilder.And(expresionFinal, expresionDepartments);
                }

IQueryable query = dataContext.Persons;
 query = query.Where(expresionFinal);

答案 4 :(得分:-1)

尝试使用.Where(s => !string.IsNullOrWhiteSpace(s))过滤掉列表中的空字符串和空字符串。

答案 5 :(得分:-1)

如果要忽略where子句中的空列表(部门和位置),则应该可以使用Any()

public List<PersonDTO> GetPersons(int pageNumber, int pageSize, List<string> departments, List<string> locations, string filterText)
{
    if (filterText == null)
    {
        filterText = "";
    }

    List<Person> personsList = _dbContext.Persons
        .Where(a => (a.firstName.Contains(filterText, StringComparison.OrdinalIgnoreCase)
                      || a.lastName.Contains(filterText, StringComparison.OrdinalIgnoreCase))
                    && (!departments.Any() || departments.Contains(a.department))
                    && (!locations.Any() || locations.Contains(a.location)))
        .Skip(pageNumber * pageSize).Take(pageSize).ToList();

    return _mapper.Map<List<PersonDTO>>(personsList);
}

及其包含的代码:

public static class StringExtensions
{
    public static bool Contains(this string source, string toCheck, StringComparison comp)
    {
        return source?.IndexOf(toCheck, comp) >= 0;
    }
}

来源:https://stackoverflow.com/a/444818/1248177

答案 6 :(得分:-1)

有几种方法可以检查列表是否为空: 1. If(list.Count()> 0) 2.最好的方法是使用“ Any”代替“ Where”,这将返回布尔值结果,如果为true,则表示有数据,否则无任何结果。

答案 7 :(得分:-1)

这应该有效。如果可以的话,在调用ToList()之前,您应该真正建立查询。这将使您能够分阶段执行操作,并使您的应用程序更高效。

public List<PersonDTO> GetPersons(int pageNumber, int pageSize, List<string> departments, List<string> locations, string filterText = "")
{
    List<Person> personList = new List<Person>();

    if (!string.IsNullOrEmpty(filterText)) {
        personsList = _dbContext.Persons
            .Where(a => (a.firstName.ToLower().Contains(filterText.ToLower()) || a.lastName.ToLower().Contains(filterText.ToLower()))
                    && departments.Contains(a.department) 
                    && locations.Contains(a.location)).ToList();
    } else {
        personList = _dbContext.Persons.ToList();
    }

        personList = personList.Skip(pageNumber * pageSize).Take(pageSize).ToList();

    return _mapper.Map<List<PersonDTO>>(personsList);
}

这是使用IQueryable的另一个示例。

public List<PersonDTO> GetPersons(int pageNumber, int pageSize, List<string> departments, List<string> locations, string filterText = "")
    {
        IQueryable<List<Person>> personQuery = _dbContext.Persons.AsQueryable();

        if (!string.IsNullOrEmpty(filterText))
        {
            personQuery = personQuery
                .Where(a => (a.firstName.ToLower().Contains(filterText.ToLower()) || a.lastName.ToLower().Contains(filterText.ToLower()))
                        && departments.Contains(a.department)
                        && locations.Contains(a.location));
        }

        personQuery = personQuery.Skip(pageNumber * pageSize).Take(pageSize);

        return _mapper.Map<List<PersonDTO>>(personQuery.ToList());
    }

这是我如何做您想做的事的一个例子。

public List<CourseSearchDetail> GetPaginated(SearchRequest searchRequest, bool admin, out int totalRecords,
        out int recordsFiltered)
    {
        var query = _courseRepo
            .GetDataTableQuery();

        if (!admin) query = query.Where(x => x.CourseDate > DateTime.Now);

        var courseList = query.ToList();

        totalRecords = courseList.Count();

        if (!string.IsNullOrEmpty(searchRequest.Search.Value))
            courseList = courseList.Where(x => x.CourseTitle.ToLower().Contains(searchRequest.Search.Value.ToLower())).ToList();

        recordsFiltered = courseList.Count();

        if (searchRequest.Order == null)
            courseList = courseList.OrderByDescending(x => x.CourseDate).ToList();
        else
            courseList = courseList.OrderResults(searchRequest);
        var skip = searchRequest.Start;
        var pageSize = searchRequest.Length;

        courseList = pageSize > 0
            ? courseList.Skip(skip).Take(pageSize).ToList()
            : courseList.ToList();

        return courseList;
    }