删除组件时,NHibernate错误地与null进行比较

时间:2012-01-26 14:37:49

标签: nhibernate mapping-by-code

我在更新实体上的组件集时遇到问题。它最初被映射为一个包,但这导致每次删除和重新插入所有条目。将它更改为一个集已解决了这个问题,但引入了一个新问题。

组件类型称为Tracking,它具有UserIDItemID的复合键以及两个可为空的日期属性。当创建其中一个DateRead设置为当前时间时,稍后将其替换为具有新日期的条目。

底层SQL NHibernate生成的where子句检查所有属性是否匹配。

问题是,另一个日期DateAcknowledged通常为空,并且生成的SQL似乎有语法错误,要对其执行null检查:= NULL而不是:{{1 },如图所示:

IS NULL

问题是,根本不需要两个日期来确定要删除的内容。只需具有检查项目ID和用户ID的位置即可。

这是我定义集合的映射代码:

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 */

以下是组件的映射:

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

有没有办法让NHibernate只在where子句中使用键,或者以正确的方式比较空值?

2 个答案:

答案 0 :(得分:2)

7.2. Collections of dependent objects部分对此进行了介绍,并指出这不受支持:

  

请注意,如果您使用的是< set>,则复合元素映射不支持无效属性。 NHibernate在删除对象时必须使用每个列值来标识记录(复合元素表中没有单独的主键列),这对于空值是不可能的。您必须在复合元素中仅使用非空属性,或者选择< list>,< map>,< bag>或< idbag>。

答案 1 :(得分:1)

有关如何使用条件删除NHibernate实体的详细说明,请参阅this answer。这应该允许您在确定要删除的项目时使用ItemIdUserId,并安全地忽略日期比较。