views:

26

answers:

2

I'm testing Fluent NHibernate with NorthWind database. Now, I've created Employee and EmployeeMap class. Source code is like below.

class Employee

public class Employee
{
    public virtual int EmployeeID { get; private set; }
    public virtual string LastName { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string Title { get; set; }
    public virtual string TitleOfCourtesy { get; set; }
    public virtual DateTime? BirthDate { get; set; }
    public virtual DateTime? HireDate { get; set; }
    public virtual string Address { get; set; }
    public virtual string City { get; set; }
    public virtual string Region { get; set; }
    public virtual string PostalCode { get; set; }
    public virtual string Country { get; set; }
    public virtual string HomePhone { get; set; }
    public virtual string Extension { get; set; }
    public virtual string Notes { get; set; }
    public virtual Employee ReportsTo { get; set; }
    public virtual string PhotoPath { get; set; }

    public virtual IList<Territory> Territories{ get; set; }

    public Employee()
    {
        Territories = new List<Territory>();
    }

    public virtual void AddTerritory(Territory territory)
    {
        territory.Employees.Add(this);
        this.Territories.Add(territory);
    }
}

class EmployeeMap

public class EmployeeMap : ClassMap<Employee>
{
    public EmployeeMap()
    {
        Table("Employees");

        Id(x => x.EmployeeID);
        Map(x => x.LastName);
        Map(x => x.FirstName);
        Map(x => x.Title);
        Map(x => x.TitleOfCourtesy);
        Map(x => x.BirthDate);
        Map(x => x.HireDate);
        Map(x => x.Address);
        Map(x => x.City);
        Map(x => x.Region);
        Map(x => x.PostalCode);
        Map(x => x.Country);
        Map(x => x.HomePhone);
        Map(x => x.Extension);
        Map(x => x.Notes);
        Map(x => x.PhotoPath);
        References(x => x.ReportsTo).Column("ReportsTo").LazyLoad();

        HasManyToMany(x => x.Territories)
        .Cascade.All()
        .Table("EmployeeTerritories")
        .ParentKeyColumn("EmployeeID")
        .ChildKeyColumn("TerritoryID");
    }
}

Then I try to load all employees from database, but all employees have reference object on ReportsTo property.

var sessionFactory = CreateSessionFactory();

using (var session = sessionFactory.OpenSession())
{
    using (session.BeginTransaction())
    {
        Console.WriteLine("All employees");

        var emp_ = session.CreateCriteria(typeof(Employee));
        var employees = emp_.List<Employee>();

        foreach (var employee in employees)
        {
            Console.WriteLine(employee.FirstName); // every employee has reference object on ReportsTo property here.
        }

        Console.Write("--------");
    }
}

I want to know, what wrong with my code and how to fixed it?

A: 

Lazy loading is not enabled by default.

public EmployeeMap()
{
    Table("Employees");
    LazyLoad();

    // etc.
}

That being said, testing with a foreach statement can be mischievous, because even if you have enabled lazy loading, the second you query for "employee.FirstName", NHibernate will hit the database and return the results. You're better off catching NHibernate's generated SQL or just using the NHibernate Profiler.

Rafael Belliard
Wrong. Lazy loading *is* enabled by default in all relationships.
Diego Mijelshon
+1  A: 

Lazy Load is enabled by default. The reference in ReportsTo is a proxy that will only be loaded from the DB if any property other than the ID is used.

Diego Mijelshon