Nano Hash - криптовалюты, майнинг, программирование

NHibernate обновляет строку перед ее удалением?

У меня странное поведение с nhibernate. Проблема в том, что nhibernate выполняет обновление перед удалением объекта. У меня есть класс категории и класс продукта. Категория имеет мешок продуктов. Когда я удаляю продукт из категории, nhibernate делает следующее:

  • Он обновляет сущность продукта, которую я удалил из коллекции
  • Он удаляет объект продукта из базы данных.

Вот отображение

  <class name="Category"> 
    <id name="Id"> 
      <generator class="hilo" /> 
    </id> 
    <property name="Name" lazy="false" length="20" /> 

    <bag name="Products" cascade="all-delete-orphan" lazy="false" 
inverse="false"> 
      <key column="CategoryId" /> 
      <one-to-many class="Product" /> 
    </bag> 
  </class> 

  <class name="Product"> 
    <id name="Id"> 
      <generator class="hilo" /> 
    </id> 
    <property name="Name" lazy="false" /> 
    <property name="Discontinued" lazy="false" /> 
    <property name="Price" lazy="false" /> 
    <many-to-one name="Category" 
             class="Category" 
             column="CategoryId" 
             cascade="none" /> 
  </class>

Вот код

    using (var session = NHibernateHelper.OpenSession()) 
    using (var transaction = session.BeginTransaction()) 
    { 
        var c1 = session.Load<Category>(32768); 
        c1.Ps.RemoveAt(0); 

        session.SaveOrUpdate(c1); 
        transaction.Commit(); 
    }

и вот результат:

exec sp_executesql N'UPDATE Product SET CategoryId = null WHERE 
CategoryId = @p0 AND Id = @p1',N'@p0 int,@p1 int',@p0=32768,@p1=65537 
go 

exec sp_executesql N'DELETE FROM Product WHERE Id = @p0',N'@p0 
int',@p0=65537 
go

Кто-нибудь может объяснить это странное поведение?

Спасибо.

21.01.2011

Ответы:


1

Измените инверсию на true в вашем определении для вашей сумки с продуктами в категории. Установка inverse на false сообщает NHibernate, что объект Category является владельцем ключа в отношении.

Если для коллекции Products установлено значение false, NHibernate рассматривает категорию как владельца отношения. Поэтому, когда коллекция Products изменяется, она выдает инструкцию обновления, чтобы удалить продукт из категории. Затем удаление происходит, потому что Продукт был удален.

22.01.2011

2

РЕДАКТИРОВАТЬ: Извините, запутался кодом; Ps не очень описательное свойство. В этом случае происходит то, что из-за способа удаления продукта (путем удаления его из коллекции в категории и последующего сохранения категории) NHibernate сначала удаляет ссылку на категорию из продукта, потому что этот продукт не больше принадлежит категории (это ключевое преобразование между объектами и таблицами; в ООП ссылка удерживается содержащим объектом, а в SQL - содержащимся объектом). Теперь запись не принадлежит ни к какой Категории; он осиротел, и вы сказали NHibernate очистить потерянные ссылки в его каскадном поведении, чтобы он выполнил удаление.

Если вы хотите сделать это с помощью всего одного оператора SQL, попробуйте следующее:

using (var session = NHibernateHelper.OpenSession()) 
using (var transaction = session.BeginTransaction()) 
{ 
    var c1 = session.Load<Category>(32768); 
    var toDelete = c1.Ps[0];
    c1.Ps.RemoveAt(0); 

    session.Delete(toDelete);
    transaction.Commit(); 
    //you shouldn't need to update the c1 object
}
21.01.2011
  • Привет, Кит, спасибо за ответ. Вы правы, но в этой ситуации я не удаляю категорию, я просто удаляю товар из категории. Таким образом, эта операция не требует отсоединения ссылок, а в моей ситуации это вообще не требуется. 22.01.2011

  • 3

    Мне такое поведение кажется нормальным. У меня мало опыта работы с NHibernate, но я считаю, что для удаления записи вы обычно вызываете метод ISession.Delete, передавая объект, представляющий запись, которую вы хотите удалить.

    В вашем случае вы можете сделать следующее:

    // delete a product
    session.Delete(c1.Ps[0]);
    

    Или, чтобы быть более ясным:

    // find the product that I want to delete
    var product = c1.Ps[0];
    
    // now delete it
    session.Delete(product);
    

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

    Обратите внимание, что в своем классе Category вы определили атрибут «каскад» отношения к классу Product следующим образом: cascade="all-delete-orphan". Поскольку ваш оператор обновления вызывает потерю этой записи продукта, NHibernate, вероятно, распознает, что запись продукта должна быть удалена в соответствии с настройкой каскада, и поэтому я предполагаю, что именно поэтому он решает выполнить оператор удаления.

    21.01.2011
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..