2017-03-28 10 views
2

을 가지고 내가 NHibernate에에 문제가 이런 종류에 직면 값 개체를 삭제하는 데 실패 :NHibernate에가 null 속성 값

난 구성 요소를 삭제하려고하면 (객체를 그 어떤 ID 등) 속성의 값으로 널 (null)이, EquatableObject이 구현 여기서

HasMany<RilevanzaFinding>(x => x.Rilevanze) 
     .Access.CamelCaseField(Prefix.Underscore) 
     .Table("RilevanzaFinding_T045") 
     .KeyColumn("int_T045_IdFinding") 
     .Cascade.AllDeleteOrphan() 
     .AsSet() 
     .Component(fee => 
     { 
      fee.References<Rating>(x => x.Rating).Column("int_T045_IdRating").Fetch.Join(); 
      fee.Map(x => x.DataFine) 
       .Column("dte_T045_DataFine")      
       .CustomSqlType("Date"); 
      fee.Map(x => x.Note) 
       .Column("nvc_T045_Note") 
       .Length(100000); 
     }); 

public class Finding : BaseObject<Finding, int> 
{ 
    private ICollection<RilevanzaFinding> _rilevanze = new List<RilevanzaFinding>(); 
    public virtual IEnumerable<RilevanzaFinding> Rilevanze 
    { 
     get 
     { 
      return _rilevanze.ToArray(); 
     } 
    } 
} 

public class RilevanzaFinding : EquatableObject<RilevanzaFinding> 
{ 
    public virtual Rating Rating { get; set; } 
    public virtual DateTime? DataFine{ get; set; } 
    public virtual string Note { get; set; } 
} 

: 조작 내가 RilevanzaFinding 오브젝트 성분의 Finding로 매핑 한 field = NULL 대신

Field IS NULL의 조건으로 변환되기 때문에 실패 같음 :

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

     TObject other = obj as TObject; 

     return Equals(other); 

    } 

    public virtual bool Equals(TObject other) 
    { 
     if (other == null) 
      return false; 

     Type t = GetType(); 

     TypeInfo typeInfo = t.GetTypeInfo();    
     IEnumerable<FieldInfo> fields = typeInfo.DeclaredFields.Where(x => x.FieldType.Name != typeof(ICollection<>).Name); 
     foreach (FieldInfo field in fields) 
     { 
      object value1 = field.GetValue(other); 
      object value2 = field.GetValue(this); 

      if (value1 == null) 
      { 
       if (value2 != null) 
        return false; 
      } 
      else if (!value1.Equals(value2)) 
       return false; 
     } 
     return true; 
    } 

을 지금은 찾는 Rilevanze의 TIS의 컬렉션에서 Rilevanza을 제거 할 때이 NHibernate에 의해 생성 된 SQL이다 : 그것은있을 것이기 때문에,

NHibernate: DELETE FROM RilevanzaFinding_T045 WHERE int_T045_IdFinding = 
@p0 AND dte_T045_DataFine = @p1 AND nvc_T045_Note = @p2 AND int_T045_IdRating 
= @p3;@p0 = 201 [Type: Int32 (0:0:0)], @p1 = NULL [Type: DateTime (0:0:0)], @p2 = 'GD675PFN2GTR9EUJ3JHPG7XFX' [Type: String (1073741823:0:0)], 
@p3 = 243 [Type: Int32 (0:0:0)] 

느릅 나무 인해 "dte_T045_DataFine = NULL" 조건을 실패 "dte_T045_DataFine IS NULL"

어떻게 올바른 조건을 만들 수 있습니까?

답변

1

set으로는 연결할 수 없습니다. NHibernate reference documentation에서

:

당신이 <set>를 사용하는 경우 복합 요소 매핑은 null로 할 수 속성을 지원하지 않습니다. Hibernate는 객체를 삭제할 때 각 열 값을 사용하여 레코드를 식별해야한다 (복합 요소 테이블에 별도의 기본 키 컬럼이 없다). 이는 null 값으로 이 될 수 없다. 복합 요소에 null이 아닌 속성 만 사용하거나 <list>, <map>, <bag> 또는 <idbag>을 선택해야합니다.

이 경우 구성 요소보다 엔티티를 매핑하고 테이블에 기본 키를 추가하는 것이 좋습니다. SQL은 그만큼 성능이 향상됩니다.

+0

onestly nhibernate 제한 문서에서 find는 where 조건에서 = null을 IS NULL로 변환하면 해결 될 수 있습니다. 지금은 NULL 값의 기본 날짜로 swtich, 그래서 난 항상 테이블에 값을 가지고 –

+0

그것은 의미 론적 변화가 될 것입니다. SQL의 경우 null은 null과 같지 않으며 해당 기준의 SQL Server가 아닌 기준 기반은 인덱스 된 열 중 하나가 모든 행에서 null 인 경우 동일한 열 값을 갖는 행에 대해 고유 한 인덱스를 허용합니다. 따라서 "동일한"값을 갖고 있지만 그 중 일부가 null 인 두 구성 요소는 동일하지 않은 것으로 간주됩니다. 그래서 NHibernate는 null 속성을 가지고있는 집합에서 어느 구성 요소를 삭제해야 하는지를 알 수 없다. –

+0

null이더라도 키가 존중됩니다. Null-1-1과 1-1-1이 다르면 널 -1 행이 2 개 허용되지 않습니다. 위의 게시 된대로 간단히 트릭은 특정 행을 검색 할 때 = null을 IS NULL로 변환 할 때마다 하나만이 발견됩니다. –