存储库的通用Linq查找方法

时间:2014-09-01 18:09:27

标签: c# linq repository-pattern

我有一个使用Repository模式的应用程序来抽象数据的检索方式。我计划使用Web服务来检索数据,但在开发过程中只会嘲笑它。但是,我仍然坚持如何使find方法正常工作。到目前为止我有以下内容,但我不确定query.Compile()是否正确(没有我发现的例子)。我收到一个编译错误,说Linq的Where方法没有超载System.Linq.Expressions.Expression。这是我到目前为止所处的位置:

public async Task<IEnumerable<Customer>> FindAsync(Expression<Func<Customer, bool>> query)
{
    var allCustomers = await GetAllAsync(true);

    return allCustomers.Where(query.Compile());
}

在某些时候,我想弄清楚如何避免检索所有客户然后再应用表达式,但我不确定如何将表达式传递给REST Web服务,以便过滤可以在数据访问层进行

2 个答案:

答案 0 :(得分:2)

我看到的Repository模式的实现通常看起来像这样(使用Entity Framework):

public class Repository<T> where T : class
{
    private readonly DbSet<T> _queryableBase;

    public Repository(DbSet<T> queryableBase)
    {
        _queryableBase = queryableBase;
    }

    public T Select(IFilter<T> filterClass)
    {
        return filterClass.Filter(_queryableBase.AsQueryable()).First();
    }
    public IEnumerable<T> SelectMany(IFilter<T> filterClass)
    {
        return filterClass.Filter(_queryableBase.AsQueryable());
    }

    public void Delete(T item)
    {
        _queryableBase.Remove(item);
    }

    public void Add(T item)
    {
        _queryableBase.Add(item);
    }
}

然后是过滤器对象:

public interface IFilter<T>
{
    IEnumerable<T> Filter(IEnumerable<T> queryableBase);
}

示例过滤实现:

class FilterChris : IFilter<ATestObject>
{
    public IEnumerable<ATestObject> Filter(IEnumerable<ATestObject> queryableBase)
    {
        return queryableBase.Where(o => o.FirstName == "Chris");
    }
}

public class ATestObject
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

请注意,过滤器可以链接。

答案 1 :(得分:1)

  

在某些时候,我想弄清楚如何避免全部检索   客户,然后应用表达式,但我不知道我是怎样的   可以将表达式传递给REST Web服务,以便进行过滤   发生在数据访问层。

假设您的客户端应用程序是用C#编写的,您可以使用breeze-sharp:

http://www.breezejs.com/breeze-sharp-documentation/query-examples#whereSimple

  

BreezeSharp与任何使用HTTP和JSON的服务进行通信。   您是否使用由Entity支持的Web API,OData或MVC提供数据   SQL Server前面的框架? Breeze有一个很好的开箱即用   故事。

BreezeSharp允许您在客户端上编写这样的代码:

var query3 = query1.Where(td => !td.IsArchived && !td.IsDone);
var activeTodos = awaitManager.ExecuteQuery(query3);