[英]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.