简体   繁体   English

存储库的通用Linq查找方法

[英]Generic Linq Find method for Repository

I have an application using the Repository pattern to abstract how data is retrieved. 我有一个使用Repository模式的应用程序来抽象数据的检索方式。 I plan on using a web service for retrieving the data, but during development will just mock it out. 我计划使用Web服务来检索数据,但在开发过程中只会嘲笑它。 However, I am stuck on how to get a find method working. 但是,我仍然坚持如何使find方法正常工作。 I have the following so far, but I am not sure that query.Compile() is the right thing to be doing (no examples I have found do that). 到目前为止我有以下内容,但我不确定query.Compile()是否正确(没有我发现的例子)。 I get a compiler error saying there is no overload for Linq's Where method that takes a System.Linq.Expressions.Expression . 我得到一个编译器错误,说Linq的Where方法没有重载需要System.Linq.Expressions.Expression Here is where I am at so far: 这是我到目前为止的地方:

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

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

At some point, I would like to figure out how to avoid retrieving all customers and then applying the expression also, but am not sure how I can pass the expression to a REST webservice so the filtering can happen at the data access layer. 在某些时候,我想弄清楚如何避免检索所有客户然后应用表达式,但我不知道如何将表达式传递给REST Web服务,因此过滤可以在数据访问层进行。

The implementations of Repository pattern I've seen generally look like this (using Entity Framework): 我见过的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);
    }
}

Then the filter object: 然后是过滤器对象:

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

Example filtering implementation: 示例过滤实现:

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; }
}

Note that filters can chain. 请注意,过滤器可以链接。

At some point, I would like to figure out how to avoid retrieving all customers and then applying the expression also, but am not sure how I can pass the expression to a REST webservice so the filtering can happen at the data access layer. 在某些时候,我想弄清楚如何避免检索所有客户然后应用表达式,但我不知道如何将表达式传递给REST Web服务,因此过滤可以在数据访问层进行。

Assuming your client app is written in C# you could use breeze-sharp: 假设您的客户端应用程序是用C#编写的,您可以使用breeze-sharp:

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

BreezeSharp communicates with any service that speaks HTTP and JSON. BreezeSharp与任何使用HTTP和JSON的服务进行通信。 Are you serving data with Web API, OData or MVC backed by Entity Framework in front of SQL Server? 您是否在SQL Server前面使用Entity Framework支持的Web API,OData或MVC提供数据? Breeze has a great out-of-the-box story. 微风有一个很好的开箱即用的故事。

BreezeSharp would allow you to write code like this on the client: BreezeSharp允许您在客户端上编写这样的代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM