Подтвердить что ты не робот

Отображение компонентов NHibernate - нулевой компонент

У меня есть отображаемая сущность, Материя, которая имеет отображаемый компонент, Травма.

Единственным свойством на травме является DateOfInjury, который является нулевым datetime.

Когда я получаю Материя, если DateOfInjury имеет значение NULL, компонент имеет значение null.

Таким образом, что-то вроде этого вопроса. Injury.DateOfInjury будет бросать.

Может кто-нибудь объяснить, если я делаю что-то очевидное, чтобы вызвать это поведение?

Я бы ожидал, что компонент Injury инициализируется nHibernate как объект и что свойство DateOfinjury имеет значение null.

Это было бы более гибким, я бы подумал?

4b9b3361

Ответ 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.

Несомненно, взломан, но, похоже, работает до сих пор для загрузки пустых компонентов и не вызывает никаких ошибок при сохранении. Используйте с осторожностью, хотя.