2011-07-18 7 views
0

Oracle10gプロバイダを使用してOracle.DataAccessを使用して外部組織からデータを読み取っています。テーブルの1つにこれらのフィールドで構成される複合IDがあります。レコードの複合IDにnull値のキープロパティが含まれているデータベースからエンティティを読み込むにはどうすればよいですか?

course: 
    institutioncode: "X11" 
    coursecode:  "N100" 
    campuscode:  "A" 
    entryyear:  2011 
    entrymonth:  10 

問題は、キャンパス・コードが外部プロバイダによってヌルの代わりに空にすることを許可されていることです。これにより、nHibernateは、コースエンティティの代わりにnull参照を含むコレクションを返します。

他のドメインオブジェクトは、このコースエンティティも参照するためにこれらのフィールドを使用します。したがって、これは実際にキーとして使用され、サロゲートキーを使用するように簡単に再マップすることはできません。

タグ3.1.0GAのソースから、この動作の原因となっているチェックはNhibernate.Type.ComponentType.Hydrate(IDataReader rs, string[] names, ISessionImplementor session, object owner)にあります。これは、キープロパティがnullになる可能性を常に拒否しています。これにより、キープロパティとキー参照プロパティのNULL値をオプションにすることができますか?

これを実行しないと、nHibernateで直接このデータを読むことをお勧めしますか?

+0

複合キーからキャンパスコードを離れることができますか?参照を制限するために、 'where'と' propertyref'を使うことができます。 – Firo

+0

@Firo、回答として控えめな参照の例を教えていただけますか?私はあなたが何を意味するのか分かりません。 –

答えて

1

ok私の最初のコメントは参考文献(ManyToOne)でうまくいきませんでした。だから私の代わりの解決策:チェックを回避するユーザータイプ。

class CourseMap : ClassMap<Course> 
{ 
    public CourseMap() 
    { 
     CompositeId() 
      .KeyProperty(c => c.InstitutionCode) 
      .KeyProperty(c => c.CourseCode) 
      .KeyProperty(c => c.CampusCode, key => key.Type(typeof(MyUserType))) 
      .KeyProperty(c => c.EntryYear) 
      .KeyProperty(c => c.EntryMonth); 
    } 
} 

class MyUserType : IUserType 
{ 
    public object Assemble(object cached, object owner) 
    { 
     return DeepCopy(cached); 
    } 

    public object DeepCopy(object value) 
    { 
     return value; 
    } 

    public object Disassemble(object value) 
    { 
     return DeepCopy(value); 
    } 

    public new bool Equals(object x, object y) 
    { 
     return object.Equals(x, y); 
    } 

    public int GetHashCode(object x) 
    { 
     return (x == null) ? 0 : x.GetHashCode(); 
    } 

    public bool IsMutable 
    { 
     get { return false; } 
    } 

    public object NullSafeGet(IDataReader rs, string[] names, object owner) 
    { 
     var value = NHibernateUtil.String.NullSafeGet(rs, names[0]); 
     return (value == null) ? string.Empty : value; 
    } 

    public void NullSafeSet(IDbCommand cmd, object value, int index) 
    { 
     string d = string.IsNullOrEmpty((string)value) ? null : (string)value; 
     NHibernateUtil.String.NullSafeSet(cmd, d, index); 
    } 

    public object Replace(object original, object target, object owner) 
    { 
     return DeepCopy(original); 
    } 

    public Type ReturnedType 
    { 
     get { return typeof(string); } 
    } 

    public SqlType[] SqlTypes 
    { 
     get { return new[] { SqlTypeFactory.GetString(100) }; } 
    } 
} 



class SomeEntityMap : ClassMap<SomeEntity> 
{ 
    public EntityMap() 
    { 
     Id(e => e.Id).GeneratedBy.Assigned(); 

     References(e => e.Course) 
      .Columns("InstitutionCode", "CourseCode", "CampusCode", "EntryYear", "EntryMonth") 
      .Fetch.Join(); // important because we can't rely on values, NULL is invalid value 
    } 
} 
2

プロパティのNULL値はサポートされていません。デザインではです。

これに対処するための2つの方法があります。

  • は、適切な代理キーを追加し、代わりにソースからの生、それを使用してのデータをインポートします。
  • NHibernateのないエンティティを処理します。