Отображение компонентов NHibernate - нулевой компонент
У меня есть отображаемая сущность, Материя, которая имеет отображаемый компонент, Травма.
Единственным свойством на травме является DateOfInjury, который является нулевым datetime.
Когда я получаю Материя, если DateOfInjury имеет значение NULL, компонент имеет значение null.
Таким образом, что-то вроде этого вопроса. Injury.DateOfInjury будет бросать.
Может кто-нибудь объяснить, если я делаю что-то очевидное, чтобы вызвать это поведение?
Я бы ожидал, что компонент Injury инициализируется nHibernate как объект и что свойство DateOfinjury имеет значение null.
Это было бы более гибким, я бы подумал?
Ответы
Ответ 1
Я думаю, что поведение по умолчанию для отображения компонентов. Документы NHibernate для компонента говорят, что если все элементы компонента равны нулю, сам компонент будет равен нулю.
Если у вас есть только одно свойство в компоненте, имеет смысл просто отобразить его как свойство NULL DateTime в классе Matter.
Ответ 2
Я также столкнулся с той же проблемой, что и NHibernate, чтобы инициализировать мой компонент, даже если все его члены равны нулю в БД. Мотивация этой реализации заключалась в том, чтобы переместить столько логики в отношении моего компонента в компонент, не имея дело с тем, что оно является нулевым или нет.
Благодаря этому сообщению я ищу объяснение, почему мои модульные тесты были неудачными для всех нулевых значений внутри компонента, были короткими. Я исправил этот фрагмент в головоломке, расширив авто-свойство моего класса компонентов ArrivalDay
и назначив новый экземпляр сам, когда назначен null:
private ArrivalDay _arrivalDay;
public ArrivalDay ArrivalDay
{
get { return _arrivalDay; }
set { _arrivalDay = value ?? new ArrivalDay(); }
}
Это работает как шарм и означает очень мало накладных расходов на класс.
Ответ 3
Я решил это, добавив это свойство в класс компонентов
public virtual bool _LoadAlways { get { return true; } set { } }
Ответ 4
Это технически приемлемое решение. Я тестировал его с устойчивостью и отсутствием связанных с переходными процессами проблем.
protected internal virtual Injury NullableInjury {get;set;}
public virtual Injury Injury
{
get{return NullableInjury ?? (NullableInjury = new Injury());
}
В Nhibernate сопоставьте свой компонент с NullableInjury.
Это решение позволяет вам оставаться без временной проблемы, описанной в решении @Oliver.
Ответ 5
fooobar.com/info/421771/... не работал у меня, но основывался на нем:
public class Injury
{
// ...
private bool dummyFieldToLoadEmptyComponent { get; set; }
}
public class MatterMap : ClassMap<Matter>
{
// ...
Component(x => x.Injury, m =>
{
// ...
m.Map(Reveal.Member<Injury>("dummyFieldToLoadEmptyComponent")).Formula("1=1").ReadOnly();
});
}
Бит Reveal.Member
предназначен для отображения частного поля в Fluent NHibernate. Мы хотим, чтобы поле было приватным, потому что мы не хотим, чтобы это свойство отображалось как часть нашего публичного интерфейса к компоненту. См. https://github.com/jagregory/fluent-nhibernate/wiki/Mapping-private-properties. Если вы не возражаете, чтобы это публично, вы могли бы использовать менее подробное отображение:
m.Map(x => x.DummyFieldToLoadEmptyComponent).Formula("1=1").ReadOnly();
Часть Formula
состоит в том, что на самом деле мы не хотим, чтобы в нашей базе данных был столбец. NHibernate выполнит эту формулу при загрузке компонента и всегда будет оценивать значение true. Я выбрал 1 = 1, так как я бы предположил, что разумно перекрестный DB.
Несомненно, взломан, но, похоже, работает до сих пор для загрузки пустых компонентов и не вызывает никаких ошибок при сохранении. Используйте с осторожностью, хотя.