Неправильное сравнение NHibernate с нулем при удалении компонента - PullRequest
4 голосов
/ 26 января 2012

В настоящее время у меня есть проблема при обновлении коллекции компонентов на объекте. Первоначально он был сопоставлен как пакет, но каждый раз все записи удалялись и вставлялись заново. Изменение его на набор исправило эту проблему, но представило новую.

Тип компонента называется Tracking, он имеет составной ключ UserID и ItemID и два свойства, которые могут содержать даты, которые могут иметь значение NULL. Когда один из них создается DateRead с установленным текущим временем, он затем заменяется записью с новой датой.

Базовый SQL NHibernate генерирует предложение where, которое проверяет соответствие всех свойств.

Проблема в том, что другая дата DateAcknowledged часто равна нулю, и сгенерированный SQL, похоже, имеет синтаксическую ошибку, чтобы выполнить нулевую проверку, выполняя это: = NULL вместо: IS NULL, как показано:

DELETE FROM TrackingTable
   WHERE  ItemId = 'a68f6dea-1c00-42e2-bc40-9fcf01121bd8' /* @p0 */
   AND UserId = 'c8aa41a4-e4c2-4347-ae6e-b48738a53b47' /* @p1 */
   AND DateRead = '2012-01-26T12:56:46.00' /* @p2 */
   AND DateAcknowledged = NULL /* @p3 */

Дело в том, что две даты вообще не нужны, чтобы определить, что удалять. Просто наличие идентификатора элемента проверки where и идентификатора пользователя подойдет.

Вот код отображения, где я определяю набор:

Set(x => x.Trackings,
         mapper =>
                {
                    mapper.Key(k => k.Column("ItemId"));
                    mapper.Table("Tracking");
                    mapper.Access(Accessor.NoSetter);
                },
                collectionMapping => collectionMapping.Component(TrackingMap.Mapping()));

А вот отображение для компонента:

public class TrackingMap
    {
        public static Action<IComponentElementMapper<Tracking>> Mapping()
        {
            return c =>
            {
                c.ManyToOne(x => x.User, a => { a.Column("UserId"); a.ForeignKey("UserId"); });
                c.Property(x => x.DateRead);
                c.Property(x => x.DateAcknowledged, a => a.NotNullable(false));
            };
        }
    }

Можно ли указать NHibernate использовать ключи только в предложении where или для правильного сравнения нулей?

Ответы [ 2 ]

2 голосов
/ 30 мая 2012

Это рассматривается в разделе 7.2.Наборы зависимых объектов , которые отмечают, что это не поддерживается:

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

, или .

1 голос
/ 26 января 2012

Пожалуйста, посмотрите этот ответ для хорошего объяснения того, как удалять сущности NHibernate, используя критерии. Это должно позволить вам использовать только ItemId и UserId при определении элементов для удаления и безопасно игнорировать сравнения дат.

...