NHibernate 4 upgrade - Cannot simultaneously fetch multiple bags

不羁岁月 提交于 2019-12-22 09:42:27

问题


I tried to upgrade NH 3.3.1.4000 to the latest version NH 4.0.2.4000 and I had an issue with FetchMany and ThenFetchMany.

In this post I learned that this old functionality is no longer valid, Breaking changes with NHibernate 4 upgrade.

What is the correct way to do this kind of fetching on the new NH version?

Code Example:

var IdsList = new List { /* Some Ids */ };
session.Query<A>()
.FetchMany(x=>x.B_ObjectsList)
.ThanFetchMany(x=>x.C_ObjectsList)
.Where(x=>IdsList.Contains(x=>x.Id))
.ToList();

Classes:

Public Class A
{
    public int Id {get;set;}
    public IList<B> B_ObjectsList{get;set;}
}

Public Class B
{
    public int Id {get;set;}
    public IList<C> C_ObjectsList {get;set;}
}

Public Class C
{
    public int Id {get;set;}
}

Mapping:

<class name="A" table="A">
<id name="Id" type="int" column="Id" unsaved-value="0">
  <generator class="identity" />
</id>
<bag name="B" table="B" inverse="false" lazy="true"
cascade="all-delete-orphan">
</class>

<class name="B" table="B">
<id name="Id" type="int" column="Id" unsaved-value="0">
  <generator class="identity" />
</id>
<bag name="C" table="C" inverse="false" lazy="true"
cascade="all-delete-orphan">
</class>


<class name="C" table="C">
<id name="Id" type="int" column="Id" unsaved-value="0">
  <generator class="identity" />
</id>
</class>

回答1:


probably

var IdsList = new List { /* Some Ids */ };
var results = session.Query<A>()
    .FetchMany(x => x.B_ObjectsList)
    .Where(x=>IdsList.Contains(x.Id))
    .ToList();

// initialize C_ObjectsList
var bIds = results.SelectMany(x => x.B_ObjectsList).Select(b => b.Id).Distinct().ToList();
session.Query<B>()
    .FetchMany(x => x.C_ObjectsList)
    .Where(b => bIds.Contains(b.Id))
    .ToList();

return results;



回答2:


If B has a reference to A you can do:

var IdsList = new List { /* Some Ids */ };
var results = session.Query<A>()
                     .Fetch(a => a.B_ObjectsList)
                     .Where(a => IdsList.Contains(a.Id))
                     .ToList();

// initialize C_ObjectsList
var aQuery = session.Query<A>()
                    .Where(x => IdsList.Contains(x.Id));

session.Query<B>()
       .Fetch(b => b.C_ObjectsList)
       .Where(b => aQuery.Contains(b.A)
       .Prefetch();

This has the advantage of not being limited by the max parameters of the DB, which in SQL server defaults to 2100. Instead of ToList(), I use this extension method:

static public void Prefetch<T>(this IQueryable<T> query)
{
    // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
    query.AsEnumerable().FirstOrDefault();
}


来源:https://stackoverflow.com/questions/27174270/nhibernate-4-upgrade-cannot-simultaneously-fetch-multiple-bags

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!