Linq 为获取生成外部联接的Nhibernate

Linq 为获取生成外部联接的Nhibernate,linq,nhibernate,join,fluent-nhibernate,linq-to-nhibernate,Linq,Nhibernate,Join,Fluent Nhibernate,Linq To Nhibernate,尽管将映射设置为Not.Nullable()和Not.LazyLoad() 出于某种原因,NH两次连接一个表,一次使用内部连接来消除WHERE,第二次使用外部连接来选择数据 当然,因为我们已经加入了数据,所以只使用加入的表是有意义的 SELECT ...Tables.. from Tasks taskentity0_, outer Cases caseentity1_, outer Grades gradeentit2_, Cases caseentity5_ WHERE ..

尽管将映射设置为
Not.Nullable()
Not.LazyLoad()

出于某种原因,NH两次连接一个表,一次使用内部连接来消除WHERE,第二次使用外部连接来选择数据

当然,因为我们已经加入了数据,所以只使用加入的表是有意义的

SELECT
     ...Tables..
from Tasks taskentity0_,
 outer Cases caseentity1_,
 outer Grades gradeentit2_,
 Cases caseentity5_ 
WHERE
....
我对此的LINQ查询是:

IQueryable<TaskEntity> tasks = TaskRepo.Find(
    t => t.DueDate <= DateTime.Now
      && (t.TaskInitials == userInitials || (t.TaskInitials == "" || t.TaskInitials == null))
      && t.Team.GST.Any
                    (x => x.Initials == userInitials
                        && x.WorkType.WorkTypeCode == t.WorkType.WorkTypeCode
                        && x.Team.TeamCode == t.Team.TeamCode
                    )
      && (t.Case.CaseOnHold <= DateTime.Now || t.Case.CaseOnHold == null || (t.SingleTask == "M" || t.SingleTask == "m"))
      && (t.Case.CaseMatter.StartsWith("0") || t.Case.CaseMatter.StartsWith("9"))
                ).Fetch(t => t.Case,FetchProvider)
想法

我们正在使用存储库模式,并重新实现了Fetch扩展方法以这种方式工作(因此传入FetchProvider)

此外,
QueryOver
在这里不是一个选项,因为我们需要
IQueryable
s

我用的是NH3.1

对于群众:

我们不再使用Fetch或LINQ,我们移动到HQL

    /// <summary>
    /// Interfaces for Fetch() statements
    /// </summary>

    public interface IFetchingProvider
    {
        IFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector);

        IFetchRequest<TOriginating, TRelated> FetchMany<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, IEnumerable<TRelated>>> relatedObjectSelector);

        IFetchRequest<TQueried, TRelated> ThenFetch<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, TRelated>> relatedObjectSelector);

        IFetchRequest<TQueried, TRelated> ThenFetchMany<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, IEnumerable<TRelated>>> relatedObjectSelector);
    }


public class NhFetchingProvider : IFetchingProvider
    {
        public IFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector)
        {
            var fetch = EagerFetchingExtensionMethods.Fetch(query, relatedObjectSelector);
            return new FetchRequest<TOriginating, TRelated>(fetch);
        }

        public IFetchRequest<TOriginating, TRelated> FetchMany<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, IEnumerable<TRelated>>> relatedObjectSelector)
        {
            var fecth = EagerFetchingExtensionMethods.FetchMany(query, relatedObjectSelector);
            return new FetchRequest<TOriginating, TRelated>(fecth);
        }

        public IFetchRequest<TQueried, TRelated> ThenFetch<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, TRelated>> relatedObjectSelector)
        {
            var impl = query as FetchRequest<TQueried, TFetch>;
            var fetch = EagerFetchingExtensionMethods.ThenFetch(impl.NhFetchRequest, relatedObjectSelector);
            return new FetchRequest<TQueried, TRelated>(fetch);
        }

        public IFetchRequest<TQueried, TRelated> ThenFetchMany<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, IEnumerable<TRelated>>> relatedObjectSelector)
        {
            var impl = query as FetchRequest<TQueried, TFetch>;
            var fetch = EagerFetchingExtensionMethods.ThenFetchMany(impl.NhFetchRequest, relatedObjectSelector);
            return new FetchRequest<TQueried, TRelated>(fetch);
        }
}

public static IFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(this IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector, Func<IFetchingProvider> FetchingProvider)
        {
            return FetchingProvider().Fetch(query, relatedObjectSelector);
        }
//
///Fetch()语句的接口
/// 
公共接口IFetchingProvider
{
IFetchRequest Fetch(IQueryable查询、表达式相关ObjectSelector);
IfetchRequestFetchMany(IQueryable查询、表达式相关ObjectSelector);
IFetchRequest ThenFetch(IFetchRequest查询,表达式相关对象选择器);
IFetchRequest ThenFetchMany(IFetchRequest查询,表达式相关对象选择器);
}
公共类NhFetchingProvider:IFetchingProvider
{
公共IFetchRequest获取(IQueryable查询、表达式相关ObjectSelector)
{
var fetch=eakeFetchingExtensionMethods.fetch(查询,relatedObjectSelector);
返回新的FetchRequest(fetch);
}
公共IFetchRequest FetchMany(IQueryable查询、表达式相关ObjectSelector)
{
var fecth=eakerFetchingExtensionMethods.FetchMany(查询,relatedObjectSelector);
返回新的获取请求(fecth);
}
公共IFetchRequest ThenFetch(IFetchRequest查询,表达式相关对象选择器)
{
var impl=作为FetchRequest的查询;
var fetch=eangefetchingextensionmethods.ThenFetch(impl.NhFetchRequest,relatedObjectSelector);
返回新的FetchRequest(fetch);
}
公共IFetchRequest ThenFetchMany(IFetchRequest查询,表达式相关对象选择器)
{
var impl=作为FetchRequest的查询;
var fetch=eangefetchingextensionmethods.ThenFetchMany(impl.NhFetchRequest,relatedObjectSelector);
返回新的FetchRequest(fetch);
}
}
公共静态IFetchRequest获取(此IQueryable查询、表达式相关ObjectSelector、Func获取提供程序)
{
返回FetchingProvider().Fetch(查询,relatedObjectSelector);
}

还不支持在NHibernate中使用linq的内部联接。更多信息可以在这里找到:

我已经添加了对它的支持


享受

存储库模式破坏了NHibernate的功能。我的观点和许多其他人都有相同的想法。看到Fetch扩展的源代码会很有帮助。从历史上更新-请记住,该代码现在已经有将近一年的历史了,没有使用过。谢谢你-将它添加到JIRA中似乎和将它添加到我的亚马逊愿望列表中一样有用-但是,嘿,哦,这可能会发生@Stuart.Sklinar很悲伤,但这是真的。这是开源的吗?你能链接到Github吗?所以我们提供了改进,fork等等…?是的,点击Nuget页面上的项目站点或者点击这里
    /// <summary>
    /// Interfaces for Fetch() statements
    /// </summary>

    public interface IFetchingProvider
    {
        IFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector);

        IFetchRequest<TOriginating, TRelated> FetchMany<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, IEnumerable<TRelated>>> relatedObjectSelector);

        IFetchRequest<TQueried, TRelated> ThenFetch<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, TRelated>> relatedObjectSelector);

        IFetchRequest<TQueried, TRelated> ThenFetchMany<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, IEnumerable<TRelated>>> relatedObjectSelector);
    }


public class NhFetchingProvider : IFetchingProvider
    {
        public IFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector)
        {
            var fetch = EagerFetchingExtensionMethods.Fetch(query, relatedObjectSelector);
            return new FetchRequest<TOriginating, TRelated>(fetch);
        }

        public IFetchRequest<TOriginating, TRelated> FetchMany<TOriginating, TRelated>(IQueryable<TOriginating> query, Expression<Func<TOriginating, IEnumerable<TRelated>>> relatedObjectSelector)
        {
            var fecth = EagerFetchingExtensionMethods.FetchMany(query, relatedObjectSelector);
            return new FetchRequest<TOriginating, TRelated>(fecth);
        }

        public IFetchRequest<TQueried, TRelated> ThenFetch<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, TRelated>> relatedObjectSelector)
        {
            var impl = query as FetchRequest<TQueried, TFetch>;
            var fetch = EagerFetchingExtensionMethods.ThenFetch(impl.NhFetchRequest, relatedObjectSelector);
            return new FetchRequest<TQueried, TRelated>(fetch);
        }

        public IFetchRequest<TQueried, TRelated> ThenFetchMany<TQueried, TFetch, TRelated>(IFetchRequest<TQueried, TFetch> query, Expression<Func<TFetch, IEnumerable<TRelated>>> relatedObjectSelector)
        {
            var impl = query as FetchRequest<TQueried, TFetch>;
            var fetch = EagerFetchingExtensionMethods.ThenFetchMany(impl.NhFetchRequest, relatedObjectSelector);
            return new FetchRequest<TQueried, TRelated>(fetch);
        }
}

public static IFetchRequest<TOriginating, TRelated> Fetch<TOriginating, TRelated>(this IQueryable<TOriginating> query, Expression<Func<TOriginating, TRelated>> relatedObjectSelector, Func<IFetchingProvider> FetchingProvider)
        {
            return FetchingProvider().Fetch(query, relatedObjectSelector);
        }