繁体   English   中英

没有LINQ扩展的NHibernate通用存储库?

[英]NHibernate generic repository without LINQ extension?

我正在寻找几天前没有结果的答案。

我正在尝试使用NHibernate为通用存储库实现IRepository接口的实现。 这是界面:

public interface IRepository<TEntity, TKey> where TEntity : BaseEntity
{
    TEntity GetById(TKey id);
    void Insert(TEntity entidad);
    void Update(TEntity entidad);
    void Delete(TEntity entidad);
    IQueryable<TEntity > Table { get; };
}

我知道ISession接口有一个扩展,可以在查询中使用LINQ,但我也知道该插件不能100%正常工作(我已经对其进行了测试,但是当我尝试执行一些复杂的查询时,它没有实现异常,所以我不能使用该插件)

我正在使用100%的ISession的QueryOver函数,所以..您是否知道将IQueroOver函数实现为IQueryable的任何方法(无需启动“ SELECT *”查询)? 如果不是,是否有其他想法可以在不使用LINQ扩展的情况下实现通用存储库模式?

非常感谢你

没有这样的事

每个人对于100%已实现的LINQ提供程序应具有的功能都有自己的定义。 有人可能希望LINQ提供程序能够将String.Equals(String, String, StringComparison)转换为使用正确排序规则的SQL表达式,但是除非创建LINQ提供程序的程序员对其进行了编程,否则它不会能够做到。 我们可能希望LINQ提供程序能够做的事情没有止境,因此每个 LINQ提供程序都有局限性。 对于LINQ提供程序,没有100%这样的事情。 这是一个无法实现的概念。 它是无限的。

因此,重要的是...

  1. 了解您的LINQ提供程序的局限性,以及
  2. 知道如何解决这些限制。

限制

使用NHibernate时,要知道局限性要困难一些,因为目前没有NHibernate LINQ提供程序的官方文档。 NH-2444 ,欢迎使用补丁!)但是,您可以知道LINQ提供程序是基于HQL构建的,因此您可以弄清楚其中的一些内容,因此LINQ也将具有HQL的任何限制。

没有NHibernate查询语法直接支持在不相关的列上执行任意的左外部联接(当然,在Native SQL之外)。 NHibernate中的查询经过设计,因此执行连接的所有信息已存储在映射中。 之后,您要做的就是指定关系,例如order.Customer ,NHibernate知道将哪些表和列连接在一起。 您应该能够使用HQL或LINQ进行任意交叉联接,然后可以添加where子句以使其表现得像内部联接,而没有左外部联接。

由于没有一种查询语法直接支持您要执行的操作,因此构建LINQ / QueryOver包装器(与现有LINQ / HQL包装器并置,并且可能实现起来很复杂)将不会给您带来任何好处。 无论您使用的是LINQ还是QueryOver,都必须采取相同的步骤来处理此查询。

解决方法

由于LINQ提供程序不可能完整,因此设计良好的LINQ提供程序必须是可扩展的。 这样,如果LINQ提供程序本身不支持所需的功能,则不会破坏您的一天。 NHibernate LINQ提供程序可以扩展。 有关更多信息,请参见Giorgetti Alessandro的博客

但是,当然,在开始编写LINQ提供程序扩展之前,我们应该检查是否有解决问题的更简单方法。 我想到了两种可能性:

解决此问题的最简单方法是将关系简单地添加到NHibernate映射中,使您能够在NHibernate查询(LINQ或其他)中利用它。 如果两列的数据类型不兼容,或者需要某种操作才能执行连接,请考虑修复数据和架构,以实现更平滑的映射。

另一个选择是通过子查询来获得创意,或者使用多个查询来模拟所需的联接将执行的操作。 例如,请参阅我的其他答案之一

...可以通过组合两个独立查询的结果来模拟此LEFT OUTER JOIN-一个可以获取订单...

 var orders = session.Query<OrderHeader>() .Fetch(x => x.CreatedBy); 

...和另一个获得没有命令的人:

 var peopleWithNoOrders = session.Query<Person>() .Where(p => !session.Query<OrderHeader>().Any(o => o.CreatedBy == p)); 

...因为left outer join等效于inner join加上非匹配的其他结果。 我不知道您要执行的联接的详细信息,但是希望这会给您足够的构想,以帮助您入门。

暂无
暂无

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

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