我对 NHibernate 还很陌生,希望通过几个地方的 linq 扩展来优化对象列表的加载。当我尝试在集合中急切加载子集合时遇到问题。 我认为伪代码更适合描述我的问题,所以假设我们有以下设置:
public interface IRepository<T> {
IQueryable<T> GetAll();
}
public class A {
public virtual int Id { get; set;}
public virtual IList<B> ListOfBs { get; set; } // mapped with HasMany and LazyLoad
public virtual IList<D> ListOfDs { get; set; } // mapped with HasMany and LazyLoad
}
public class B {
public virtual IList<C> ListOfCs { get; set; } // mapped with HasMany and LazyLoad
}
public class C {
public virtual int MyProperty { get; set; }
}
public class D {
}
我想检索 ID 为 1,2,3 的类
A
的所有行,并希望所有子集合都立即加载,尽管它们被映射为惰性:
var repoA = Ioc.GetInstance<IRepository<A>>();
IQueryable<A> result = repoA.GetAll().Where(a => a.Id == 1 || a.Id == 2 || a.Id == 3);
根据 NHibernate Docs,在查询中多次使用
FetchMany
可能会导致笛卡尔积,可以通过使用未来的结果来避免。下面的代码会产生 2 个额外的查询来获取结果中所有 A
的两个集合。 (在到数据库的单次往返中),但当然不会获取B.ListOfCs
。
result.FetchMany(a => a.ListOfBs).ToFuture();
result.FetchMany(a => a.ListOfDs).ToFuture().GetEnumerable();
我如何获取所有
ListOfCs
中的 B
?
我尝试将 FetchMany
与 ThenFetchMany
一起使用,但这会导致错误。
// the following results in "Error: "Cannot simultaneously fetch multiple bags""
result
.FetchMany(a => a.ListOfBs)
.ThenFetchMany(b => b.ListOfCs);
foreach(var a in result) {
// do something with a.ListOfBs[0].ListOfCs[0].MyProperty
}
有什么方法可以使用 linq 在单个附加数据库调用中获取所有相关的
ListOfCs
吗? (我读到正在使用 session.QueryOver 但会话隐藏在我正在工作的层中)
预先感谢您的帮助。
结果 .FetchMany(a => a.ListOfBs) .ThenFetchMany(b => b.ListOfCs);
尝试使用
SelectMany
来获取已获取的集合:
result.FetchMany(a => a.ListOfBs).ToFuture();
result.SelectMany(a => a.ListOfBs).FetchMany(b => b.ListOfCs).ToFuture();