在NHibernate中急切地加载多级子实体会导致重复问题
我有一个模型类,其中包含一些图像和一些功能:在NHibernate中急切地加载多级子实体会导致重复问题,nhibernate,nhibernate-criteria,Nhibernate,Nhibernate Criteria,我有一个模型类,其中包含一些图像和一些功能: public class Model { public int ModelId { get; set; } public string ModelName { get; set; } public virtual IList<Feature> ModelFeatures { get; set; } public virtual IList<ModelImage> ModelImages { ge
public class Model
{
public int ModelId { get; set; }
public string ModelName { get; set; }
public virtual IList<Feature> ModelFeatures { get; set; }
public virtual IList<ModelImage> ModelImages { get; set; }
}
public class ModelImage
{
public virtual int ModelImageId { get; set; }
public virtual Model Model { get; set; }
public virtual Resource Image { get; set; }
public virtual int DisplayOrder { get; set; }
}
public class Feature
{
public virtual int FeatureId { get; set; }
public virtual string Title { get; set; }
public virtual string Text { get; set; }
}
公共类模型
{
公共int ModelId{get;set;}
公共字符串ModelName{get;set;}
公共虚拟IList ModelFeatures{get;set;}
公共虚拟IList模型映像{get;set;}
}
公共类模型映像
{
公共虚拟int ModelImageId{get;set;}
公共虚拟模型模型{get;set;}
公共虚拟资源映像{get;set;}
公共虚拟整数显示顺序{get;set;}
}
公共类功能
{
公共虚拟int FeatureId{get;set;}
公共虚拟字符串标题{get;set;}
公共虚拟字符串文本{get;set;}
}
现在我想急切地加载模型图像和模型功能,我使用:
item = session.CreateCriteria<Model>()
.Add(NHibernate.Criterion.Expression.Where<Model>(o => o.ModelId == id))
.SetFetchMode("ModelImages", NHibernate.FetchMode.Eager)
.SetFetchMode("ModelImages.Image", NHibernate.FetchMode.Eager)
.SetFetchMode("ModelFeatures", NHibernate.FetchMode.Eager)
.SetResultTransformer(NHibernate.Transform.Transformers.DistinctRootEntity)
.UniqueResult<Model>();
item=session.CreateCriteria()
.Add(NHibernate.criteria.Expression.Where(o=>o.ModelId==id))
.SetFetchMode(“ModelImages”,NHibernate.FetchMode.Eager)
.SetFetchMode(“modelmages.Image”,NHibernate.FetchMode.Eager)
.SetFetchMode(“ModelFeatures”,NHibernate.FetchMode.Eager)
.SetResultTransformer(NHibernate.Transform.Transformers.DistincTrotenty)
.UniqueResult();
但结果包含重复的ModelImage和ModelFeatures,
如何将结果转换器(如distinctrout)应用于这些子集合
谢谢我将把查询分为两部分:
item = session.CreateCriteria<Model>()
.Add(NHibernate.Criterion.Expression.Where<Model>(o => o.ModelId == id))
.SetFetchMode("ModelFeatures", NHibernate.FetchMode.Eager)
.UniqueResult<Model>();
session.CreateCriteria<Model>()
.Add(NHibernate.Criterion.Expression.Where<Model>(o => o.ModelId == id))
.SetFetchMode("ModelImages", NHibernate.FetchMode.Eager)
.SetFetchMode("ModelImages.Image", NHibernate.FetchMode.Eager)
.UniqueResult<Model>();
item=session.CreateCriteria()
.Add(NHibernate.criteria.Expression.Where(o=>o.ModelId==id))
.SetFetchMode(“ModelFeatures”,NHibernate.FetchMode.Eager)
.UniqueResult();
session.CreateCriteria()
.Add(NHibernate.criteria.Expression.Where(o=>o.ModelId==id))
.SetFetchMode(“ModelImages”,NHibernate.FetchMode.Eager)
.SetFetchMode(“modelmages.Image”,NHibernate.FetchMode.Eager)
.UniqueResult();
第二个查询只是继续填充从第一个查询返回的“item”对象的集合,因此不需要使用第二个查询的返回值
如果希望在一次往返中执行这两个查询,可以使用Future()而不是UniqueResult(),然后使用item.Value实际执行查询。谢谢Erik
在NHibernate中没有一个标准的方法来实现这一点,这真是令人恼火。或者我有设计问题?无论如何,我还记得为了避免重复的实体,我们可以在映射中使用集合而不是包
所以我改变了:
<bag name="ModelImages" table="ModelImages" cascade="all-delete-orphan" inverse="true">
<key column="ModelId"/>
<one-to-many class="ModelImage"/>
</bag>
到
<set name="ModelImages" table="ModelImages" cascade="all-delete-orphan" inverse="true">
<key column="ModelId"/>
<one-to-many class="ModelImage"/>
</set>