NHibernate:深度访问虚拟和延迟加载

Kri*_*s-I 3 nhibernate

我认为在一次采访中问这个有点荒谬.但如果面试官问......需要回答.

深入解释:

  1. 为什么属性和方法必须是虚拟的
  2. 懒惰加载如何工作

问候,

Dmi*_*try 7

您将不得不查看NHibernate源代码以获取更多详细信息,但我的理解如下:通过使用在运行时生成的代理替换类来实现延迟加载.代理继承自类,因此它可以"拦截"方法调用并懒惰地加载实际数据.这种拦截只有在方法和属性是虚拟的情况下才有效,因为客户端代码通过对类的引用来调用它们.客户端代码可能不知道它确实使用代理(从类派生).实际的延迟加载逻辑要复杂得多,但这大致是正在发生的事情:

public class Customer {
    public virtual String Name {
        get { return _name; }
    }
}

// code like this gets generated at runtime:
public class CustomerProxy7461293476123947123 : Customer {

    private Customer _target;

    public override String Name {
        get {
            if(_target == null){
                _target = LoadFromDatabase();
            }
            return _target.Name;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,当客户端实际调用"Name"时,数据才会被加载:

Customer customer = Session.Load<Customer>(1);  // <-- proxy is returned
// or
Customer customer = salesman.FavoriteCustomer;  // <-- proxy is returned

...

String name = customer.Name; // <-- proxy's Name will be called, loading data
Run Code Online (Sandbox Code Playgroud)

除了不需要在运行时生成集合之外,类似的机制用于集合.NHibernate内置持久性集合,可以懒散地加载项目.