2012-01-26 21 views
4

我在更新實體上的組件集合時目前遇到問題。它最初被映射爲一個包,但是每次都會導致所有條目被刪除並重新插入。將其更改爲一組已解決該問題,但引入了一個新問題。NHibernate在刪除組件時錯誤地與null進行比較

該組件類型被稱爲Tracking它有一個組合鍵UserIDItemID和兩個屬性是可空日期。當其中一個被創建的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 */ 

問題是,這兩個日期根本不需要確定要刪除的內容。只需具備檢查項目ID和用戶ID即可。

這裏是映射代碼,我定義集合:

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子句中還是以正確的方式比較空值?

+1

我們可以看到映射文件嗎? – nachojammers

+0

可能看到hbm?,對於我們這些不習慣通過代碼映射的人。 – Dan

回答

2

這是由部分7.2. Collections of dependent objects該報告指出,這是不支持覆蓋:

請注意,一個組合元素的映射不支持可能爲空的屬性,如果您使用的是<設置>。 NHibernate必須在刪除對象時使用每個列值來標識記錄(組合元素表中沒有單獨的主鍵列),這對於空值是不可能的。您必須在複合元素中只使用非空屬性或選擇<列表>,<地圖>,<包>或<idbag>。

1

請參閱this answer瞭解如何使用標準刪除NHibernate實體。這應該允許您在確定要刪除的項目時僅使用ItemIdUserId,並安全地忽略日期比較。

+0

我實際上並沒有明確地刪除條目,我只是從集合中添加和刪除條目並在父條目上調用更新 –