Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用NHibernate加载子财产和孙子孙女_C#_Nhibernate_Fetch_Eager Loading_Linq To Nhibernate - Fatal编程技术网

C# 使用NHibernate加载子财产和孙子孙女

C# 使用NHibernate加载子财产和孙子孙女,c#,nhibernate,fetch,eager-loading,linq-to-nhibernate,C#,Nhibernate,Fetch,Eager Loading,Linq To Nhibernate,我有一个类模型图,如下所示 A { ISet<B> Bset; int Id;} B { ISet<C> Cset; D Dprop; } D { int Id; } A{ISet Bset;int Id;} B{ISet Cset;D Dprop;} D{int Id;} 所有属性都配置为延迟加载。我试图编写一个查询来加载所有的图形,从a开始。理想情况下,它应该是 var result = (from conf in s.Query<A>()

我有一个类模型图,如下所示

A { ISet<B> Bset; int Id;}
B { ISet<C> Cset; D Dprop; } 
D { int Id; }
A{ISet Bset;int Id;}
B{ISet Cset;D Dprop;}
D{int Id;}
所有属性都配置为延迟加载。我试图编写一个查询来加载所有的图形,从a开始。理想情况下,它应该是

var result = (from conf in s.Query<A>()
    .FetchMany(x => x.Bset)
    .ThenFetch(x => x.Dprop)
    // line below doesn't work, because x 
    //is a D object here, and not a "B", as I would like
    .ThenFetchMany(x => x.Cset) 
     where conf.Id == 42
     select conf).SingleOrDefault();
var result=(来自s.Query()中的conf)
.FetchMany(x=>x.Bset)
.ThenFetch(x=>x.Dprop)
//下面的行不起作用,因为x
//这里是一个D对象,而不是我想要的“B”
.ThenFetchMany(x=>x.Cset)
其中conf.Id==42
选择conf.SingleOrDefault();
因此,当我试图获取Cset关联时,我需要做的是“上升一级”。有人知道怎么做吗


我正在使用Nhibernate 4.1.0。

您必须从
FetchMany
重新开始

var result = (from conf in s.Query<A>()
    .FetchMany(x => x.Bset)
    .ThenFetch(x => x.Dprop)
    .FetchMany(x => x.Bset)
    .ThenFetchMany(x => x.Cset) 
     where conf.Id == 42
     select conf).SingleOrDefault();
var result=(来自s.Query中的conf

如果需要关闭会话,然后使用实体,则必须通过对其延迟加载的属性调用
NHibernateUtil.Initialize()
,在实体上循环来触发延迟加载。由于延迟加载批处理,它不会对已加载的实体执行任何操作。

另一种选择是在关闭会话之前将实体转换为视图模型。

Frédréric回答说,一种方法是重复FetchMany子句,从图中的第一个实体开始再次到达Cset:

var result = (from conf in s.Query<A>()
.FetchMany(x => x.Bset).ThenFetch(x => x.Dprop)
.FetchMany(x => x.Bset).ThenFetchMany(x => x.Cset) 
 where conf.Id == 42
 select conf).SingleOrDefault();
var result=(来自s.Query()中的conf)
.FetchMany(x=>x.Bset)。然后fetch(x=>x.Dprop)
.FetchMany(x=>x.Bset)。然后FetchMany(x=>x.Cset)
其中conf.Id==42
选择conf.SingleOrDefault();
使用集合进行关联,该解决方案不会在生成的SQL或NHibernate返回的对象中产生笛卡尔乘积

另一种解决方案是使用未来查询,该查询将在实际查询被激发时执行(就在它之前):

var queryAux=(来自s.Query()中的conf)
.FetchMany(x=>x.Bset)
.ThenFetch(x=>x.Dprop)
其中conf.Id==42选择conf.ToFuture();
var result=(来自s.Query()中的conf)
.FetchMany(x=>x.Bset)
.ThenFetch(x=>x.Dprop)
其中conf.Id==42
选择conf.SingleOrDefault();

这样,将向数据库激发2个查询,但它也可以工作。

您可以使用'longhand'LINQ并使用
let
关键字吗?即
let b=Bset
我该如何做?我尝试了类似的方法(从s.Query()中的conf.FetchMany(x=>x.Bset)。然后FetchMany(x=>x.Dprop)let b=(从s.Query()中的ent.FetchMany(x=>Cset)其中ent.A.Id==42选择结束)其中conf.Id==42选择conf.SingleOrDefault();但它不会在let b=(…)中执行子查询。我不确定。我是从
QueryOver
得到这个想法的,在那里你可以使用变量作为别名,然后在查询中引用它们。我希望
let
关键字可以提供相同的功能。
var queryAux =  (from conf in s.Query<A>()
    .FetchMany(x => x.Bset)
    .ThenFetch(x => x.Dprop) 
    where conf.Id == 42 select conf).ToFuture();

var result = (from conf in s.Query<A>()
    .FetchMany(x => x.Bset)
    .ThenFetch(x => x.Dprop)    
     where conf.Id == 42
     select conf).SingleOrDefault();