I have a problem with SetFetchMode call in Crite开发者_如何转开发ria API in following query:
DetachedCriteria.For<User>()
.Add<User>(u => u.Status == UserStatus.Live)
.CreateAlias("UniqueId", "uid")
.CreateAlias("Companies", "comp")
.Add(Restrictions.Disjunction()
.Add(Restrictions.Like("uid.Uid", context.Text, MatchMode.Anywhere))
.Add(Restrictions.Like("comp.Name", context.Text, MatchMode.Anywhere)))
.SetFetchMode("Companies", FetchMode.Eager));
My Classes:
public class User : EntityBase<int>
{
public virtual UniqueId UniqueId { get; set; }
public virtual ISet<Company> Companies { get; set; }
}
public class Company : EntityBase<int>
{
public virtual string Name { get; set; }
}
public class UniqueId : EntityBase<int>
{
public virtual string Uid { get; set; }
}
And mappings
public sealed class UserMap : ClassMap<User>
{
public UserMap()
{
Table("users");
Id(x => x.Id).GeneratedBy.Native().Column("id");
References(x => x.UniqueId).Column("int_unique_id_ref");
HasMany(x => x.Companies)
.KeyColumn("user_id")
.Inverse()
.AsSet();
}
}
public sealed class CompanyMap : ClassMap<Company>
{
public CompanyMap()
{
Table("company");
Id(x => x.Id).GeneratedBy.Native().Column("id");
Map(x => x.Name).Column("name");
}
}
public sealed class UniqueIdMap : ClassMap<UniqueId>
{
public UniqueIdMap()
{
Table("tbl_trading_partner_unique_id");
Id(x => x.Id).GeneratedBy.Native().Column("int_id");
Map(x => x.Uid).Column("str_unique_id");
}
}
But after getting users list Nhibernate is quering data base again to get companies collection for each user once again. NHibernate just ignores call of SetFetchMode, because I have tried to write something like this:
.SetFetchMode("NotExistingProp", FetchMode.Eager)
Nhibernate doesn't thows any exceptions.
I also have tried to set Lazy to false in the mappings, but it also didn't help. Have no idea how to fix it, can somebody
and after that Nhibernate loaded collection with entities. But he is still ignoring SetFetchMode, I can write anything there.
The solution is not so obvious. We have changed
.CreateAlias("Companies", "comp")
to
.CreateAlias("Companies", "comp", JoinType.LeftOuterJoin)
Since you are using .CreateAlias("Companies", "comp")
, NHibernate can't eager-load the collection, as you could be using restrictions on that alias.
My overall suggestion is to never use eager load on collections. Use batch_size
or this trick instead.
精彩评论