簡體   English   中英

使用延遲加載的對象進行休眠和平等檢查

[英]Hibernate and Equality checks with lazy loaded objects

休眠讓我玩得很開心。 像這樣的函數:

public class Key
{
    public virtual bool IsEqual(Key key)
    {
        return this == key;
    }
}

如果參數與調用IsEqual的實例相同,則可以期望此函數始終返回true:

Assert.IsTrue(MyKey.IsEqual(MyKey));

但這僅是情況,只要實例“ myKey”不是延遲加載的對象/代理。 一個KeyProxy會將調用委托給包裝的內部Key對象,這將使包裝的對象與Proxy對象進行比較(這將失敗)。

基本上,這里也討論了它: NHibernate,代理和平等

那里的解決方案有點令人失望。 覆蓋等於以比較主鍵屬性的缺點是,它僅適用於已經具有值的對象,而新對象在保存之前沒有主鍵值。 我可以嘗試強制新對象直接接收有效的主鍵值,但這聽起來並不是解決此問題的好方法。

有沒有更好的(更一般的)方法來處理這種情況? 難道不是要覆蓋Equals並與唯一的(非持久)屬性進行比較嗎?

這樣的東西?

public object Identifier {get; private set;}

public Key()
{
    Identifer = new object();
}

  public override bool Equals(object obj)
  {
     if (obj == null)
     {
        return false;
     }
     Key k = obj as Key;
     if (k == null)
     {
        return false;
     }
     return this.Identifier == key.Identifier;
  }

為了克服此問題和其他問題,例如使用標識列作為主鍵,我們在域模型的基類中添加了GUID,對象創建由工廠類處理,工廠類為每個實體提供了GUID,然后將其持久化為實體的一部分。

然后將GUID用於比較實體,基本上,我們在Equals()和GetHashCode()方法中使用它。

    public override int GetHashCode()
    {
        return this.EqualityIdentifier.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        IDomainObject Obj = obj as IDomainObject 

        if (Obj == null)
        {
            return false;
        }

        return this.EqualityIdentifier == Obj.EqualityIdentifier;
    }

為了對性能產生最小的影響,我決定使用一個非持久的只讀int屬性“標識符”,該屬性由一個小的靜態且線程安全的數字生成器方法填充(延遲/首次訪問)。

  private static int _equalityIdentifierSequence;

  private static int GenerateEqualityIdentifier()
  {
     Interlocked.Increment(ref _equalityIdentifierSequence);         
     return _equalityIdentifierSequence;
  }

我很滿意這樣一個事實,即從不同的會話加載的但代表相同實體的兩個對象被視為“不相等”,因此GUID策略對我而言並不那么有希望。 與它們的包裝對象相比,代理的原始問題似乎可以用此解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM