Отображение компонента NHibernate - нулевой компонент - PullRequest
12 голосов
/ 21 апреля 2009

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

Единственное свойство в Injury - DateOfInjury, которое может иметь значение datetime.

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

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

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

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

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

Ответы [ 5 ]

10 голосов
/ 21 апреля 2009

Я думаю, что это поведение по умолчанию для сопоставления компонентов. Документы NHibernate для компонента говорят, что если все элементы компонента равны нулю, сам компонент будет просто нулевым.

Если у вас есть только одно свойство в компоненте, возможно, имеет смысл просто отобразить его как свойство DateTime с нулевым значением в классе Matter.

5 голосов
/ 09 октября 2009

Я также столкнулся с той же проблемой, когда ожидал, что NHibernate инициализирует мой компонент, даже если все его элементы в БД равны нулю. Моей мотивацией для этой реализации было перенести как можно больше логики, касающейся моего компонента, в компонент, не имея дело с тем, является ли он нулевым или нет.

Благодаря этой записи мой поиск объяснения, почему мои модульные тесты не выполнялись для всех нулевых значений внутри компонента, был коротким. Я исправил эту часть в головоломке, расширив auto-свойство класса моего компонента ArrivalDay и назначив себе новый экземпляр, когда ему присвоено значение null:

private ArrivalDay _arrivalDay;
public ArrivalDay ArrivalDay
{
    get { return _arrivalDay; }
    set { _arrivalDay = value ?? new ArrivalDay(); }
}

Это работает как заклинание и означает очень небольшие накладные расходы на содержащий класс.

2 голосов
/ 25 июня 2012

Я решил эту проблему, добавив это свойство в класс компонентов

public virtual bool _LoadAlways { get { return true; } set { } }
1 голос
/ 17 мая 2013

Это технически осуществимое решение. Я проверил это с настойчивостью и не вызвал переходных проблем.

protected internal virtual Injury NullableInjury {get;set;}
public virtual Injury Injury 
{
   get{return NullableInjury ?? (NullableInjury = new Injury()); 
}

В Nhibernate сопоставьте ваш компонент с NullableInjury. Это решение позволяет устранить проблему без временных проблем, о которых сообщалось в решении @Oliver.

0 голосов
/ 11 июня 2015

https://stackoverflow.com/a/11187173/206297 не работал для меня, но опираясь на это:

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.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...