linq - Nhibernate 为 fetch 生成 OUTER JOIN

标签 linq nhibernate join fluent-nhibernate linq-to-nhibernate

尽管将映射设置为 Not.Nullable()Not.LazyLoad()
出于某种原因,NH 将两次加入表,一次使用 INNER JOIN 来安抚 WHERE,第二次使用 OUTER JOIN 来选择数据。

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

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)

我的引用映射:
        References(x => x.Case).Column("ta_c_ref").Not.Nullable();

想法?

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

另外,QueryOver<T>这里不是一个选项,因为我们需要 IQueryable s..

我正在使用 NH 3.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);
        }

最佳答案

我已经添加了对它的支持!!

https://www.nuget.org/packages/NHibernate.Linq.InnerJoinFetch

享受!!!

关于linq - Nhibernate 为 fetch 生成 OUTER JOIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10104949/

相关文章:

sql - 基于子字符串连接2个sql表

c# - 选择一个 IEnumerable<Class> 到一个新的 IEnumerable<Class2>

c# - NHibernate 异常 "Session is closed! Object name: ' ISession'。”

mysql - 使用 MySQL 对连接表应用过滤器

c# - NHibernate QueryOver : How to join unrelated entities?

nhibernate - Fluent Nhibernate 中的自定义 Tuplizer

MySQL选择其他表中没有匹配列的行

c# - 从 EF Core 2 迁移到 EF Core 3

.net - PLINQ 更新失败

c# - LINQ 中按子表分组