2017-03-28 7 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; } 
} 

:条件はiがFindingの成分としてマッピングRilevanzaFindingオブジェクトを有するfield = NULL代わりにField IS NULL

として翻訳されるため、操作が失敗します等しい:私が見つけRilevanze TISのコレクションからRilevanzaを削除すると

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; 
    } 

は今のNHibernateによって生成されたSQLです:それは"dte_T045_DataFine IS NULL"

だろうので、

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"条件に失敗しました

どのようにすれば正しい状態を書くことができますか?

答えて

1

setではできません。 NHibernate reference documentationから

あなたが<set>を使用している場合、複合要素のマッピングがヌル可能な プロパティをサポートしていないことに注意してください。 NHibernateは、オブジェクトを削除するときに各カラム の値を使用しなければなりません(コンポジット要素テーブルには別の プライマリキーカラムがありません)。ヌル値では ではありません。コンポジット要素内でヌル以外の プロパティのみを使用するか、または<list>,<map><bag>または <idbag>を選択する必要があります。

私の意見では、このケースのコンポーネントよりもエンティティをマップして、主キーをテーブルに追加する方が良いです。ところで、あなたのSQLはパフォーマンスが向上します。

+0

onestly nhibernateの制限文書内での検索は、where from whereがwhere NULLであると解釈すると解決できます。今のところnull値のデフォルト日付にswtichするので、私はいつもテーブルの値を持っています –

+0

意味の変更になります。 SQLの場合、NULLはNULLと等しくなく、インデックスベースの列の1つがすべての行でNULLである場合、同じ列値を持つ行に対してユニークなインデックスを許可することもできます(SQL Serverは関係ありません)。したがって、「同じ」値を有するがそのうちのいくつかがヌルである2つの成分は、同じであるとはみなされない。そのため、NHibernateは、ヌルプロパティを持つコンポーネントがセット内で削除されるべきかどうかを特定できません。 –

+0

キーはnullでも尊重されます。ヌルがある行は1つしか存在しません.Null-1-1と1-1-1は異なります.2つのヌル-1-1行は許可されません。上に掲載されているように単純にトリックは、特定の行を検索するときに= NULLをIS NULLに変換することです。 –

関連する問題