我正在实施基本搜索服务,并且会向其中注入几个不同的存储库。存储库有一个方法,允许像这样使用表达式:
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,知道是否有办法避免它。
答案 0 :(得分:0)
直接问题:不,您需要将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();
}
}
答案 1 :(得分:0)
是的,您可以这样使用
Func<YourModel, bool> Expression;
Expression = x => x.Value == 1;
return _repo.Where(Expression));