是否可以简化Entity Framework的LINQ表达式?

时间:2016-04-04 20:28:50

标签: c# entity-framework linq linq-to-entities linq-expressions

我正在实施基本搜索服务,并且会向其中注入几个不同的存储库。存储库有一个方法,允许像这样使用表达式:

    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,知道是否有办法避免它。

2 个答案:

答案 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));