【问题标题】:Compiled Linq with Generic Repository Design Pattern使用通用存储库设计模式编译 Linq
【发布时间】:2011-07-16 11:15:51
【问题描述】:
我一直在网上寻找,但我还没有找到任何关于此的信息。正如我们所知,Linq 为我们提供了 CompiledQuery,它在运行之前将表达式转换为 T-SQL。我正在尝试设计一个通用存储库来与我的 EF 交互,但除了编译 Linq 查询之外。如果有人能对此有所了解,那就太好了:)
【问题讨论】:
标签:
linq
generics
entity-framework-4
linq-to-entities
repository-pattern
【解决方案1】:
这几乎是不可能的,因为如果你想预编译查询,你必须知道它。使用通用存储库,您通常只有这个:
public interface IRepository<T>
{
IQueryable<T> GetQuery();
}
因此,使用存储库实例的代码负责定义查询。预编译需要具体的存储库,其中包含以下方法:
IEnumerable<Order> GetOrdersWithHeaderAndItemsByDate(DateTime date, int take, int skip);
IEnumerable<OrderHeader> GetOrderHeadersOrderedByCustomer(int take, int skip);
等等
显然,您几乎无法在通用存储库中准备此类查询,因为它们依赖于具体实体。
【解决方案2】:
您正在寻找 Specification pattern 的实现。基本上,这是创建一个 Specification 对象,其中包含过滤查询所需的信息。通过使用规范,您可以拥有一个Generic Repository 实现,并将您的自定义查询逻辑放入规范中。规范基类看起来像:
public class Specification<TEntity>
{
public Specification(Expression<Func<TEntity, bool>> predicate)
{
_predicate = predicate;
}
public bool IsSatisfiedBy(TEntity entity)
{
return _predicate.Compile().Invoke(entity);
}
public Expression<Func<TEntity,bool>> PredicateExpression{
get{ return _predicate; }
}
private Expression<Func<TEntity, bool>> _predicate;
}
关于使用实体框架实现规范模式的非常有用的文章可以在http://huyrua.wordpress.com/2010/07/13/entity-framework-4-poco-repository-and-specification-pattern/找到