问题
Assuming I run the following code:
var placementCriteria = DetachedCriteria.For<ResidentialPlacementClientService>();
placementCriteria.Add(Restrictions.Le("StartDate", effectiveDate));
placementCriteria.Add(Restrictions.Ge("EndDate", effectiveDate));
placementCriteria.SetFetchMode("CaseClient.CaseFile", FetchMode.Eager);
placementCriteria.SetFetchMode("CaseClient.Incomes", FetchMode.Eager);
placementCriteria.SetFetchMode("CaseClient.ClientProfile", FetchMode.Eager);
placementCriteria.SetFetchMode("CaseClient.ClientProfile.Person", FetchMode.Eager);
placementCriteria.SetFetchMode("VendorService", FetchMode.Eager);
placementCriteria.SetFetchMode("VendorService.Vendor", FetchMode.Eager);
using (var session = OpenSession())
{
using (var tx = session.BeginTransaction())
{
residentialPlacements = placementCriteria.GetExecutableCriteria(session).List<ResidentialPlacementClientService>();
}
}
The "Incomes" property on my is populated correctly.
Now when I add criteria on incomes, the property is no longer being fetched eagerly.
var placementCriteria = DetachedCriteria.For<ResidentialPlacementClientService>();
placementCriteria.Add(Restrictions.Le("StartDate", effectiveDate));
placementCriteria.Add(Restrictions.Ge("EndDate", effectiveDate));
placementCriteria.SetFetchMode("CaseClient.CaseFile", FetchMode.Eager);
placementCriteria.SetFetchMode("CaseClient.Incomes", FetchMode.Eager);
placementCriteria.SetFetchMode("CaseClient.ClientProfile", FetchMode.Eager);
placementCriteria.SetFetchMode("CaseClient.ClientProfile.Person", FetchMode.Eager);
placementCriteria.SetFetchMode("VendorService", FetchMode.Eager);
placementCriteria.SetFetchMode("VendorService.Vendor", FetchMode.Eager);
var caseClientCriteria = placementCriteria.CreateCriteria("CaseClient", JoinType.InnerJoin);
var incomesCriteria = caseClientCriteria.CreateCriteria("Incomes", JoinType.InnerJoin);
incomesCriteria.Add(Restrictions.Le("StartDate", effectiveDate));
incomesCriteria.Add(Restrictions.Or(Restrictions.Ge("EndDate", effectiveDate),
Restrictions.IsNull("EndDate")));
incomesCriteria.Add(Restrictions.Eq("IncomeType", incomeType));
using (var session = OpenSession())
{
using (var tx = session.BeginTransaction())
{
residentialPlacements = placementCriteria.GetExecutableCriteria(session).List<ResidentialPlacementClientService>();
}
}
Why does NHibernate do this? How can I change my query/criteria so that the property is fetched eagerly?
Thanks.
回答1:
if you have filters on an association then NH cant be sure that all entities of the association are returned to initialize the association collection. you can issue a Select for the ids and then fetch the entities with associations eagerly
...
placementCriteria.SetProjection(Projections.Id());
residentialPlacements = session.CreateCriteria<ResidentialPlacementClientService>()
.Add(Subqueries.In("Id", placementCriteria))
.SetFetchMode("CaseClient.CaseFile", FetchMode.Eager);
.SetFetchMode("CaseClient.Incomes", FetchMode.Eager);
.SetFetchMode("CaseClient.ClientProfile", FetchMode.Eager);
.SetFetchMode("CaseClient.ClientProfile.Person", FetchMode.Eager);
.SetFetchMode("VendorService", FetchMode.Eager);
.SetFetchMode("VendorService.Vendor", FetchMode.Eager);
.List<ResidentialPlacementClientService>();
来源:https://stackoverflow.com/questions/8142710/nhibernate-setfetchmode-doesnt-work-with-nested-criteria