[英]Is it possible to simplify this LINQ expression for Entity Framework?
我正在实现一个基本的搜索服务,并向其中注入了几个不同的存储库。 存储库有一个方法,允许像这样使用表达式:
public IEnumerable<T> Select(Expression<Func<T, bool>> predicate)
{
return _dbSet.Where(predicate).AsEnumerable().ToList();
}
我目前在我的搜索服务中有这样的声明:
searchResult.FoundCustomers = _customerRepository.Select(x =>
x.FirstName.StartsWith(searchString) ||
x.LastName.StartsWith(searchString) ||
x.City.StartsWith(searchString) ||
x.Country.StartsWith(searchString) ||
x.Phone.StartsWith(searchString) || x.Phone.EndsWith(searchString)).ToList();
有没有办法改进LINQ? searchString
的重复性似乎没有必要,但我对 LINQ 还不够了解,无法知道是否有办法避免它。
对于您的直接问题:不,您需要将searchString
与您希望包含在搜索中的每个字段进行比较。 但是,有一些方法可以改善存储库用户的体验。
例如,您可以在您的存储库中实现一个搜索方法,然后在您的用户代码中您只需要调用该方法。 如果您希望像现在一样进一步过滤结果,您还可以包含一个可选的谓词:
public IEnumerable<T> Search( string searchString, Expression<Func<T, bool>> predicate )
{
var query = _dbSet.Where( x =>
x.FirstName.StartsWith( searchString ) ||
// ...
x.Phone.EndsWith( searchString ) );
if( null != predicate )
{
query = query.Where( predicate );
}
return query.ToList();
}
用法:
var searchResults = _customerRepository.Search( searchString );
您还可以使用自定义属性对可搜索字段进行属性,然后使用这些属性动态创建查询。 这需要预先进行一些工作(最好将其实现留给另一个问题),但可以以通用方式完成,以便您的所有存储库都能从中受益。
用法示例:
public class Customer
{
[SearchField( Mode = SearchMode.StartsWith )]
public string FirstName { get; set; }
public string DontSearchMe { get; set; }
[SearchField( Mode = SearchMode.StartsWith | SearchMode.EndsWith )]
public string Phone { get; set; }
}
public abstract class Repository<T>
{
public IEnumerable<T> Search( string searchString )
{
var predicate = //generate predicate from attributed properties on class T and searchString parameter
return _context.Set<T>().Where( predicate ).ToList();
}
}
是的,你可以这样使用
Func<YourModel, bool> Expression;
Expression = x => x.Value == 1;
return _repo.Where(Expression));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.