Почему мой класс сохраняет одну коллекцию в базе данных, а не другую? - PullRequest
4 голосов
/ 05 марта 2012

Это сводит меня с ума.Я могу получить одну из коллекций для сохранения в классе, но не в другой.

У меня есть класс с именем Category

public Category()
{
    Items = new List<Item>();
    Prices = new List<Price>();
}

, который имеет эти два метода, которые в значительной степениидентичны.Конструкторы устанавливают свойство с именем Category и их Name и Price соответственно.

public virtual Item AddItem(string name)
{
    var item = new Item(this, name);
    Items.Add(item);
    return item;
}

public virtual Price AddPrice(decimal price)
{
    var price = new Price(this, price);
    Prices.Add(price);
    return price;
}

Отображения

public class CategoryMap : ClassMap<Category>
{
    public CategoryMap()
    {
       // Other properties

       HasMany(x=>x.Items).Cascade.AllDeleteOrphan();
       HasMany(x=>x.Prices).Cascade.AllDeleteOrphan();
    }
}

Как видите, две коллекции отображаются наточно так же.

Карты для Price и Item имеют одинаковое отображение

References(x=>x.Category);

Насколько я могу судить, почти все в этих двух идентичны.Вот проблема

category.AddItem(someName);
session.Save(category);    // Works

category.AddPrice(somePrice);
session.Save(category);    // Doesn't work

Они находятся в файле, который я использую для заполнения тестовой базы данных.Сохранение элемента работает нормально.Сохранение цены не дает.Классы и отображения идентичны.Я не могу понять.

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

session.Save(new Price(category, 1));

Так почему Category сохраняет одну коллекцию, а не другую?Я запустил профилировщик, и класс даже не пытается сохранить коллекцию Price.

Обновление:

Как отметил Гейб в комментарии, если я поменяю местами вызовы, чтобы Price была вызванадо Item цена входит в базу данных, а Item нет.

Если после каждого обновления коллекции я звоню session.Flush(), она работает нормально.Должен ли я это делать или есть способ исправить мое отображение, чтобы оно работало?

1 Ответ

1 голос
/ 05 марта 2012

Попробуйте поменять местами порядок вызовов (сначала добавьте цену, затем пункт), чтобы увидеть, действительно ли это проблема с отображением Price или проблема заключается в том, что второй вызов не удался.Что касается flush - в большинстве случаев вам не нужно явно вызывать flush, это то, что nHibernate будет делать в фоновом режиме, когда это необходимо ( подробности здесь ).Режим сброса - это не проблема отображения (это свойство сеанса, которое вы можете установить, но, как правило, вам не нужно).

Если вы заключаете код в транзакцию, flush нетребуется.Если нет, то так и должно быть, и это может быть вашей проблемой.

using (var tx = Session.BeginTransaction()) {

    category.AddItem(someName);
    category.AddPrice(somePrice);
    session.Save(category);

    tx.Commit();
}

update : Мне кажется, я знаю, в чем заключалась ваша проблема.Учитывая ваш код, похоже, что вы создаете новый объект category и заполняете его данными.На первом Save() nHibernate выполняет автоматическую очистку, потому что он не может присвоить category_id дочерней коллекции, пока не получит ее из базы данных.Но во второй раз, category имеет идентификатор, поэтому сеанс не нужно немедленно очищать.nHibernate не общается с базой данных, когда это не нужно.Решение, как я уже упоминал выше, состоит в том, чтобы всегда использовать транзакции, чтобы указать, когда вы закончите делать свое дело.

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