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

C# 没有LINQ扩展的NHibernate通用存储库?,c#,linq,nhibernate,repository,C#,Linq,Nhibernate,Repository,我正在寻找几天前的答案,但没有结果 我正在尝试使用NHibernate实现通用存储库的IRepository接口。以下是界面: public interface IRepository<TEntity, TKey> where TEntity : BaseEntity { TEntity GetById(TKey id); void Insert(TEntity entidad); void Update(TEntity entidad); void

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

我正在尝试使用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; };
}
公共接口i假设,其中tenty:BaseEntity
{
TEntity GetById(TKey id);
空白插入物(TEntity entidad);
无效更新(TEntity entidad);
无效删除(TEntity entidad);
IQueryable表{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%这样的事情。 这是一个无法实现的概念。 它是无限的

因此,重要的是

  • 了解LINQ提供商的限制,以及
  • 知道如何克服这些限制
  • 局限性 对于NHibernate,了解其局限性比应该知道的要困难一些,因为目前没有NHibernate LINQ提供程序的官方文档。 (,欢迎使用修补程序!) 但是,只要知道这个LINQ提供程序是在HQL之上构建的,您就可以了解其中的一些情况,所以HQL的任何限制,LINQ也会有

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

    由于没有任何查询语法直接支持您想要做的事情,因此构建LINQ/QueryOver包装器(与现有的LINQ/HQL包装器类似,并且可能实现起来也同样复杂)将一事无成。 无论您使用的是LINQ还是QueryOver,都必须采取相同的步骤来处理此查询

    权变措施 由于LINQ提供程序不可能是完整的,因此设计良好的LINQ提供程序必须是可扩展的。 这样,如果LINQ提供程序在本机上不支持您所需的功能,它不会毁了您的一天。 可以扩展NHibernate LINQ提供程序。 有关更多信息,请参阅

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

    处理这个问题最简单的方法是简单地将关系添加到NHibernate映射中,使您能够在NHibernate查询(LINQ或其他)中利用它。 如果这两个列是不兼容的数据类型,或者在执行连接之前需要某种操作,请考虑修复数据和架构,以便实现更平滑的映射。 另一个选择是创造性地使用子查询,或者使用多个查询来模拟所需的联接。例如,请参见我的一个:

    。。。这种左-外连接可以通过组合两个单独查询的结果来模拟-一个用于获取订单

    var orders = session.Query<OrderHeader>()
        .Fetch(x => x.CreatedBy);
    
    var orders=session.Query()
    .Fetch(x=>x.CreatedBy);
    
    。。。还有一个是为了得到没有命令的人:

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

    。。。因为
    左外部联接
    相当于
    内部联接
    加上非匹配的附加结果。我不知道您正在尝试执行的连接的详细信息,但希望这将为您提供足够的想法以开始使用。

    您好,James,查询函数是NHibernate的另一个函数。Linq扩展我不能使用它的原因是,Linq扩展尚不支持某些
    join
    函数,我需要它
    左外部联接
    在不相关的实体上不受支持,这是真的。我不知道如何将
    QueryOver
    API转换为LINQ提供程序API(据我所知,您就是做不到),因此您要么使用LINQ提供程序并仔细解决不受支持的功能,要么公开
    IQueryOver
    。顺便说一句,我认为90%的时候都不需要存储库模式……请纠正我的错误。对于左侧外部联接,NHibernate不提供联合功能。因此,您必须(通过ToList()之类的方式)获取数据,以便可以使用Linq to对象来操作数据。由于联盟支持的原因,您不能使用Linq向NHibernate提供商提供的代理。您是对的。NHibernate不支持UNION,但无论如何,您都不会在这里使用UNION。UNION要求从两个查询返回的列集相同,但因为