Ключевым моментом здесь является то, что Number
является виртуальным.
A.B
загружается ленивым. NHibernate создает прокси для B
, который переопределяет каждое виртуальное свойство в классе. При первом обращении к одному из свойств, отличных от Id
, NHibernate загрузит данные из базы данных для заполнения объекта.
Поскольку этот прокси-класс является подклассом B
, конструктор B
будет вызываться перед прокси-конструктором. Когда конструктор B
устанавливает виртуальное свойство Number
, он вызывает свойство Number
, как определено в подклассе прокси, который еще не был инициализирован.
Более подробное обсуждение конструкторов и наследования см. В http://www.yoda.arachsys.com/csharp/constructors.html
Чтобы исправить это, преобразуйте любые свойства, которые вы хотите установить в конструкторе, чтобы использовать вспомогательные поля вместо авто-свойств, затем установите поле вместо свойства в конструкторе.
public class B
{
public B()
{
_number = 1;
}
public virtual int Id { get; private set; }
private int _number;
public virtual int Number
{
get { return _number; }
set { _number = value; }
}
}
Это немного более многословно, но эффективно избегает касания виртуальных методов или свойств в конструкторе.