Fluent NHibernate + Disable LazyLoad

12,688

Solution 1

Lazy loading means that the cars collection will be loaded only when you access the cars property. So when you turn this off, when loading a person you will always also load all his cars. To see if this "works" for you, you can open up SQL profiler (or grab the trial for NHibernate profiler), and debug your code. When you step through your code you can see if the cars collection is loaded right away, or only when you first access it.

In short, I don't think you've done something wrong, just misunderstood the concept.

Solution 2

If you are using the Load method try the Get instead. Load always returns a proxy and loads lazily iirc. Beware of SELECT N+1 though.

EDIT: After re-reading other comments it probably works as expected. Doron already explained how is lazy loading supposed to work. So if you do NOT want to load all the cars together with a person, then lazy loading should be enabled. Lazy loading is already enabled by default, because if you eagerly load all your collections, this results in a SELECT N+1, as mentioned before. That is, one select for the person and N for cars. Such behavior is usually not desired, hence my warning :) Lazy loading means that collections will be loaded only if explicitly asked for.

Share:
12,688
ebb
Author by

ebb

Updated on June 04, 2022

Comments

  • ebb
    ebb almost 2 years

    Hey there, I've tried to disable LazyLoad on my collections without luck... The code I've tried so far is:

    // Person.cs

    public class Person
    {
        public virtual int Id { get; private set; }
        public virtual string FirstName { get; set; }
        public virtual IList<Car> Cars { get; set; }
    
        public Person()
        {
            Cars = new List<Car>();
        }
    
        public virtual void AddCar(Car car)
        {
            Cars.Add(car);
        }
    }
    
    public class PersonMap : ClassMap<Person>
    {
        public PersonMap()
        {
            Id(x => x.Id);
            Map(x => x.FirstName);
            HasMany(x => x.Cars).KeyColumn("PersonId").Cascade.AllDeleteOrphan().Not.LazyLoad();
            Table("Persons");
        }
    }
    

    // Car.cs

    public class Car
    {
        public virtual int Id { get; set; }
        public virtual string CarName { get; set; }
        public virtual Person Person { get; set; }
    }
    
    public class CarMap : ClassMap<Car>
    {
        public CarMap()
        {
            Id(x => x.Id);
            Map(x => x.CarName);
            HasOne(x => x.Person).Not.LazyLoad();
            Table("Cars");
        }
    }
    

    Any suggestions?

    Thanks in advance!

  • Patko
    Patko over 13 years
    Which FluentNH version are you using? It appears there was a problem with HasMany and Not, see support.fluentnhibernate.org/discussions/help/….
  • ebb
    ebb over 13 years
    Might be.. How would I then get a Person object without all the Car object thats related to that Person?
  • Diego Mijelshon
    Diego Mijelshon over 13 years
    @ebb By leaving the default, which is to be lazy.
  • ebb
    ebb over 13 years
    @Diego Mijelshon - Hmm.. wondering why Lazyloading is called evil then.. always thought that lazyloading meant that it would load all related entities for an Entity. @Doron Yaacoby, you were right.. The NHibernate profiler actually catch 2 SQL statements.. one to get the Person Object and another to get Car Object(s) related to that Person.
  • Diego Mijelshon
    Diego Mijelshon over 13 years
    @ebb lazy loading means the opposite of that. And is only called "evil" by people who don't understand how to use it.
  • Patko
    Patko over 13 years
    @ebb, actually eager loading is the one that is evil. Lazy loading is quite nice and charming, as long as you have your session open :)
  • ebb
    ebb over 13 years
    Thanks for the explanation about the difference between lazy and eager loading!
  • James Gregory
    James Gregory over 13 years