2009-04-08 5 views
1

개체의 키 속성을 기반으로하는 값의 동일성을 구현하기 위해 추상 기본 클래스에서 Equals 및 GetHashCode를 재정의했습니다. 내 주된 목적은 Find 또는 FirstOrDefault 대신 컬렉션에 Contains 메서드를 사용하여 인스턴스가 이미 컬렉션에 추가되었는지 확인하는 것입니다.새 개체에 대한 값 평등 비교

public abstract class Entity 
{ 
    public abstract Guid Id { get; } 

    public override bool Equals(object obj) 
    { 
     if (obj == null) 
     { 
      return false; 
     } 

     if (obj.GetType() != GetType()) 
     { 
      return false; 
     } 

     var entity = (Entity)obj; 
     return (entity.Id == Id); 
    } 

    public override int GetHashCode() 
    { 
     return Id.GetHashCode(); 
    } 

} 

이 방법의 문제점은 지속 및 (NHibernate에 의해 생성) ID를 취득했습니다 전에 내 모든 오브젝트가 동일한 것입니다. 내가 잘못하고 있니? 생성자에서 ID를 생성 할 수 있지만 int ID를 사용하는 다른 프로젝트에 대해 동일한 패턴을 구현하고자하므로 분명히 작동하지 않습니다.

Equals를 재정의하는 모든 객체는 객체가 인스턴스화 된 직후 동일한 객체의 다른 인스턴스와 같습니다.

편집 추가 : 다음 날 우려하는 시나리오는 다음과 같습니다 추가 방법에서 내 컬렉션, 나는 컬렉션이 이미 객체가 추가 될 포함되어 있지 않은지 확인하기 위해 검사를하고 있습니다. new'ed up 객체가 모두 같다면, 두 개의 새로운 객체를 콜렉션에 추가 할 수 없습니다.

답변

2

동일한 컨텍스트와 결합 된 엔티티의 참조 신원을 나타내는 NHibernate 보증은 데이터베이스 신원과 동일합니다. 따라서 Equals() 및 GetHashCode()를 구현할 필요가 없으므로 Equals() 및 GetHashCode()를 재정의 할 필요가 없습니다.

NHibernate Reference Documentation10.3. Considering object identity을 참조하십시오.

또한, 데이터베이스 생성 키를 컨텍스트와 사용하여 새로운 엔티티를 통합하는 것은 데이터베이스에 엔티티를 영구히 유지하고 엔티티의 키를 생성 된 키로 설정해야합니다.

+0

좋은 지적은 ... 나는 ISessions들 사이에 컬렉션에 대한 참조를 유지하지 않을 것이라고 생각합니다. –

1

생성자에서 ID 또는 적어도 종류의 식별자를 얻어야합니다.

ID가 설정되지 않았거나 기본값 인 경우; 분명히 Equals 메서드는 ID를 설정하지 않은 동일한 유형의 객체에 대해 true를 반환합니다.

+0

나는 그것을 시도하기 전까지 나에게 분명하지 않았다, 고마워. –

0

ID가 초기화되지 않은 경우 "같지 않음"을 반환하면 도움이 될 수 있습니까?

public override bool Equals(object obj) 
{ 
    if (obj == null) 
    { 
     return false; 
    } 

    if (obj.GetType() != GetType()) 
    { 
     return false; 
    } 

    var entity = (Entity)obj; 
    if ((Id == Guid.Empty) || (entity.Id == Guid.Empty)) 
    { 
     return false; 
    } 
    return (entity.Id == Id); 
} 
0

당신의 결정에 영향을 미치는 주요 세부 사항이있다 :

... 내가 INT ID를 사용하는 다른 프로젝트에 대해 동일한 패턴을 구현하고 싶습니다 ...

일반적으로 데이터베이스에 ID가 생성되어 고유성을 적용합니다. 이제 GUID가 있으므로 값을 생성하기 위해 데이터베이스에 의존 할 필요가 없습니다. GUID가 고유 한 것으로 보장됩니다. 틀린 이유로 패턴을 따르지 마십시오 :)

그래서 생성자에서 GUID 값을 생성하십시오. 데이터베이스에서 엔티티를 가져올 때 NHibernate가 값을 덮어 쓸 수 있도록 세터가 있어야합니다.

또한 DBA가 GUID 및 데이터베이스 조각화와 관련된 경우 COMB GUIDs을 사용하는 것이 좋습니다.