Обновление NHibernate 4 - Невозможно одновременно получить несколько пакетов
Я попытался обновить NH 3.3.1.4000 до последней версии NH 4.0.2.4000, и у меня возникла проблема с FetchMany и ThenFetchMany.
В этом посте я узнал, что эта старая функциональность больше не действует, ломая изменения с обновлением NHibernate 4.
Как правильно сделать этот выбор для новой версии NH?
Пример кода:
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();
Классы:
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;}
}
Отображение:
<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>
2 ответа
Решение
Наверное
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;
Если B имеет ссылку на A, вы можете сделать:
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();
Это имеет преимущество в том, что не ограничивается максимальными параметрами БД, которые в SQL-сервере по умолчанию равны 2100. Вместо ToList()
Я использую этот метод расширения:
static public void Prefetch<T>(this IQueryable<T> query)
{
// ReSharper disable once ReturnValueOfPureMethodIsNotUsed
query.AsEnumerable().FirstOrDefault();
}