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.

有帮助吗?

解决方案

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>();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top