我在更新实体上的组件集时遇到问题。它最初被映射为一个包,但这导致每次删除和重新插入所有条目。将它更改为一个集已解决了这个问题,但引入了一个新问题。
组件类型称为Tracking
,它具有UserID
和ItemID
的复合键以及两个可为空的日期属性。当创建其中一个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子句中使用键,或者以正确的方式比较空值?
答案 0 :(得分:2)
7.2. Collections of dependent objects部分对此进行了介绍,并指出这不受支持:
请注意,如果您使用的是< set>,则复合元素映射不支持无效属性。 NHibernate在删除对象时必须使用每个列值来标识记录(复合元素表中没有单独的主键列),这对于空值是不可能的。您必须在复合元素中仅使用非空属性,或者选择< list>,< map>,< bag>或< idbag>。
答案 1 :(得分:1)
有关如何使用条件删除NHibernate实体的详细说明,请参阅this answer。这应该允许您在确定要删除的项目时使用ItemId
和UserId
,并安全地忽略日期比较。