Почему добавление этой строки портит мое отображение NHibernate? - PullRequest
2 голосов
/ 23 апреля 2011

У меня очень простая карта классов

public class ContentMap : ClassMap<Content>
{
    public ContentMap()
    {
       // Basic property mapping

       // Parent property mapping
       References(x => x.Category).Column("CategoryId");
    }
}

Используя это, мои отображения работают отлично, а свойство Category не равно нулю.

Если я попытаюсь добавить эту строку ниже первой ссылки

References(x => x.LastActive).Column("LastActiveSubCategoryId");

Мои отображения идут не так.

Если LastActiveSubCategoryId равно нулю, Category отображается нормально. Если он не равен нулю, LastActiveSubCategoryId будет установлен, но тогда CategoryId будет равен нулю.

Сами фактические свойства просты

public virtual Category Category { get; set; }

public virtual SubCategory LastActive { get; set; }

Нет ничего сложного в отображениях Category или SubCategory. Они очень похожи на класс ContentMap (только с одной ссылочной линией)

Есть идеи, что вызвало бы такое поведение? Могу ли я использовать только одну ссылку?

Обновление

Я посмотрел на SQL, и это то, что, кажется, происходит, надеюсь, кто-то может помочь мне понять, почему.

Сущность Content вставляется в базу данных очень хорошо с CategoryId и LastActiveSubCategoryId null.

Объект Category вставляется, а затем оператор обновления обновляет Content, обновляя только поле CategoryId и ничего больше.

Если бы не было SubCategory, все было бы хорошо в этот момент.

Если есть SubCategory, то через несколько операторов он вставляется, а затем Category обновляется. В операторе update изменяются несколько различных значений (некоторые не должны быть такими, как они не изменились со времени вставки), включая CategoryId и SubCategoryId. За исключением того, что CategoryId равно нулю, а LastActiveSubCategoryId - нет.

Так почему бы CategoryId быть нулевым в обновлении?

Обновление 2

Код, который я использую для вставки объектов, просто для некоторых базовых тестов. Вот соответствующие биты кода:

Category category = new Category();
dao.Save(category);

Content content = new Content();
category.AddContent(content); // Adds it to a list, like in the tutorial mBotros posted
dao.Save(Content);

SubCategory subCategory = new SubCategory();
content.AddSubCategory(subCategory);
dao.Save(subCategory);

// On the Content class
public virtual void AddSubCategory(SubCategory subCategory)
{
   SubCategories.Add(subCategory);
   LastActive = subCategory;
}

Ответы [ 2 ]

1 голос
/ 26 апреля 2011

В вашей схеме базы данных есть циклическая ссылка, которая может усложнить вставку строк.
Content ссылки SubCategory и SubCategory ссылки Content.Если бы вы попытались вставить строки, используя простой старый SQL, вы бы не смогли бы сделать это:

/* this line does not work because SubCategory 2 does not exist yet */
insert into Content (Id, LastActiveSubCategoryId) values (1, 2);
insert into SubCategory (Id, ContentId) values (2, 1);

Вместо этого вам пришлось бы сделать что-то вроде этого:

insert into Content (Id, LastActiveSubCategoryId) values (1, null);
insert into SubCategory (Id, ContentId) values (2, 1);
update Content set LastActiveSubCategoryId = 2 where Id = 1;

Вы должны помнить об этом, когда сохраняете свои сущности NHibernate.Измените AddSubCategory, чтобы не устанавливать LastActive.Сначала сохраните две сущности, затем закройте цикл.

// ... code to save Category and Content, then...

SubCategory subCategory = new SubCategory();
content.AddSubCategory(subCategory); // modified to *not* set LastActive
dao.Save(subCategory);

content.LastActive = subCategory;
dao.Update(content);
0 голосов
/ 23 апреля 2011

Вы упоминаете LastActiveId, которого нет в коде, который вы показали.

Вы случайно пытаетесь отобразить столбец как справочное и скалярное свойство?

Обновление : либо ваш фрагмент кода еще не завершен, либо вы пропустили транзакцию / сброс, который приведет к обновлению. Кроме того, есть ли у вас коллекция (не показана) с именем SubCategories и , свойство с именем LastActive?

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