2016-03-30 11 views
0

返されたデータをSQLからクラスを含むクラスに変換しようとすると、NHibernateで迷惑なエラーが発生し続けます。私はこれらのクラスを言うことができます。NHibernate - クラス内のクラスに変換する?

[DataContract()] 
public class Person { 
    [DataMember] 
    public string Name { get; set; } 
    [DataMember] 
    public Dog Dog { get; set; } 
} 
[DataContract()] 
public class Dog { 
    [DataMember] 
    public int Age { get; set; } 
} 

このSQLクエリがあります。

SELECT 
    p_name AS 'Name', 
    p_dog_age AS 'Dog.Age' 
FROM People WHERE p_name = 'Foo'; 

そして、Personクラスにこれを変換するI

var person = Session.CreateSQLQuery(Sql.GetPerson) 
       .SetResultTransformer(new AliasToBeanResultTransformer(typeof(Person))) 
       .Future<Person>().FirstOrDefault(); 

私はこれを行うたびに、私はそれがのプロパティを見つけることができないという不満次のエラー

An exception of type 'NHibernate.PropertyNotFoundException' occurred in NHibernate.dll but was not handled in user code 

を取得Dog.Ageとそれはsetterプロパティを持たないということです。私はそれが可能でなければならないことを知っているが、私はそれを把握することはできません。

SQLクエリから返される値がnullではないことがわかります。

+0

私はあなたのソリューションを見て、それがよさそうです。しかし、変圧器を延長することなくそれを行うことはできないのですか? –

答えて

0

ソリューション

周りを探して、いくつかの異なったアプローチを試みた後、私はこの思い付きました。

private void doStuff(){ 
    var listOfRows = Session.CreateSQLQuery(Sql.GetPerson) 
     .List(); 

    var listOfPersonRows = new List<Person>(); 

    if (listOfRows.Count != 0) 
    { 
     for (var i = 0; i < listOfRows.Count; i++) 
     { 
      var item = (object[])listOfRows[i]; 
      listOfPersonRows.Add(ConvertToRow(item)); 
     } 
    } 
} 

private Person ConvertToRow(object[] item) 
{ 
    var personRow = new Person(); 

    personRow.Name = (string)item[0]; 
    personRow.Dog.Age = (int)item[1]; 


    return personRow; 
} 

この方法では、複数回ではなく1回だけデータベースを照会するだけです。

+0

Nhibernateは、きちんとしたデータリーダーと配列データのマッピングを隠すのに本当に良いです。私の答えを見て、多分あなたを助けるでしょう! – increddibelly

1

コンポーネントをマップしようとしているようです。 使用FluentNHibernate:あなたは、このための4つのカラムを持つテーブル必要があると思い

public class PersonMap : ClassMap<Person> 
{ 
    public PersonMap() 
    { 
     Table("Person"); 
     Id(p => p.Id, "Id").GeneratedBy.Native().Not.Nullable(); 
     Map(p => p.Name, "Name").Length(255).Not.Nullable(); 

     Component(p => p.Dog, d => 
     { 
      d.Map(dog => dog.Name, "DogName").Not.Nullable(); 
      d.Map(dog => dog.Age, "DogAge").Not.Nullable(); 
     } 
    }  
} 

  • IDを
  • 名(個人名)
  • dogname(人の犬の名前)
  • dogage(犬の年齢)

しかし、もし人に2匹の犬がいたら?または犬がいない?

public class PersonMap : ClassMap<Person> 
{ 
    public PersonMap() 
    { 
     Table("Person"); 
     Id(p => p.Id, "Id").GeneratedBy.Native().Not.Nullable(); 

     References(p => p.Dog, "Dog").Nullable(); 
    } 
} 

public class DogMap : ClassMap<Dog> 
{ 
    Map(d => d.Id, "Id").GeneratedBy.Native(); 

    References(p => p.Person, "Person").Nullable(); 
    Map(d => d.Name, "Name").Not.Nullable(); 
    Map(d => d.Age, "Age").Not.Nullable(); 
    }  
} 

これは2つのテーブルを必要とし、IDを参照する2つの外部キーの恩恵を受けます。

あなたが直接人から犬の名前と年齢を照会することができますNHibernateはのLINQの実装を使用して:

var dog = 
    _session.Query<Person>() 
      .Where(p => p.Name == "Charlie Brown") 
      .Where(p => p.Dog.Name == "Snoopy") 
      .Select(p => p.Dog) 
      .SingleOrDefault(); 
+0

FluentNHibernateやマッピングはまったく使用されていません。それは残念ながら解決策ではありません。そうでなければ、そのような参照は間違いなく解決策になりました。 –

関連する問題