这些是我使用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);
}
答案 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;
}
}
答案 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;
}