NHibernate manually control fetching

2019-07-21 20:28发布

问题:

I am using NHibernate and I want to control fetching related entities manually.

Here is my sample entity

public class Post
{
    public virtual long Id { get; set; }
    public virtual string Title { get; set; }
    public virtual User User { get; set; }
    public virtual IList<Like> Likes { get; set; }
    public virtual IList<Tag> Tags { get; set; }
}

The behvaiour I expect is as follows:

session.Query<Post>().ToList();

After this kind of query I want Post entities to have:

  1. Primitive properties are set
  2. User property is not null but only have Id property set.
  3. Likes and Tags are null or empty collection

-

session.Query<Post>()
    .Fetch(p => p.User)
    .Fetch(p => p.Tags)
    .ToList();

And after this kind of query I want Post entities to have:

  1. Primitive properties are set
  2. User property is not null and properties are set.
  3. Tags is not null and all items have all properties set
  4. Likes is null or empty collection

Basically what I want from NHibernate is, not to fetch any related entities unless I ask for it to fetch and not cause an NHibernate specific exception (LazyInitialization etc.) when I try to access not fetched properties. The behaviour I expect is not lazy nor eager.

Before "what have you tried" comments, I tried almost all combinations with LazyLoad(), Not, Fetch etc. in Fluent NHibernate mapping configuration along with both statless and stateful sessions.

回答1:

I can't figure out how to deal with uninitialized instances without validate before call a reference:

NHibernateUtil.IsInitialized(entityOrCollection)

And / or

NHibernateUtil.IsPropertyInitialized(obj, "propertyName")


回答2:

One option is to setting the other collections to null as soon as you loaded your collection,

var list = session.Query<Post>()
    .Fetch(p => p.User)
    .Fetch(p => p.Tags)
    .ToList();
list.ForEach(i => i.Likes = null);

But you should not persist them (since you are using a stateless session I don't believe you intend to persist them anyway).