2017-10-26 16 views
0

私は最近、非常によく似た質問をしましたが、タイトルがクラスを指している間、私のコンテンツはタプルを参照していました。タプルの代わりにクラスを代入しようとすると、私はTargetParameterCountException: Parameter count mismatch.の例外を受け取ります。NHibernateをカスタムクラスにマップする方法を教えてください。

How can I get NHibernate to map to a Tuple or Class?


私は、データベースからの結果のリストを取得するには、次の方法があります。

これは一般的にうまくいきます。しかし、私は上記のメソッドを呼び出すメソッドを変更しました。これに、作品

public IList<FooBarResult> FindResults(FooBarTask st) 
{ 
    return DataAccess.Find<FooBarResult>(DetachedCriteria.For<FooBarResult>() 
     .Add(Restrictions.Eq("Task", st))).ToList(); 
} 

(私はFooBarResultの全体を返すようにしたくないとして、その上にちょうど特定の列)。

public IList<MyCustomClass> FindResults(FooBarTask st) 
{ 
    var typeConstructor = typeof(MyCustomClass).GetConstructors()[0]; 
    return DataAccess.Find<MyCustomClass>(DetachedCriteria.For<FooBarResult>() 
     .Add(Restrictions.Eq("Task", st)) 
     .SetProjection(
      Projections.ProjectionList() 
       .Add(
        Projections.Property("FieldOne") //this is a DateTime 
       ) 
       .Add(
        Projections.Property("FieldTwo") //this is a Guid 
       ) 
       .SetResultTransformer(Transformers.AliasToBeanConstructor(typeConstructor)) 
     ) 
    ); 
} 

これはクラスです。前述したように

public class MyCustomClass 
{ 
    public MyCustomClass() 
    { 
     //placeholder 
    } 

    public MyCustomClass(DateTime FieldOne, Guid FieldTwo) 
    { 
     this.FieldOne = FieldOne; 
     this.FieldTwo = FieldTwo; 
    } 

    public DateTime FieldOne { get; set; } 
    public Guid FieldTwo { get; set; } 
} 

return crit.GetExecutableCriteria(InstanceSession).List<T>();コードを実行しているとき、私はTargetParameterCountException: Parameter count mismatch.例外を取得。

MyCustomClassのリストを返す方法はありますか?

答えて

1

var typeConstructor = typeof(MyCustomClass).GetConstructors()[0]; 

あなたが得ます最初に、デフォルトのコンストラクタとその署名は明らかに一致しません。

var typeConstructor = typeof(MyCustomClass).GetConstructors()[1]; 

しかし、きれいな解決策は、(テストされていないとも少し単純化された)これらの線に沿って何かのようになります。:あなたのケースのための最も簡単な修正はあり

var typeConstructor = GetMatchingConstructorOrThrow<MyCustomClass> 
    (typeof(DateTime), typeof(Guid)); 

// ... 

private ConstructorInfo GetMatchingConstructorOrThrow<T>(params Type[] requiredSignature) 
where T : class 
{ 
    foreach (var c in typeof(T).GetConstructors()) 
    { 
     var currentSignature = c.GetParameters().Select(p => p.ParameterType); 
     if (currentSignature.SequenceEqual(requiredSignature)) 
     { 
      return c; 
     } 
    } 

    throw new NoMatchingConstructorFoundException(); 
} 
+0

はあなたの助けがあったが、そんなにありがとうございました非常に貴重な:) –

1

私はこれをテストしていませんが、あなたはTransformers.AliasToBeanは、変圧器の仕事をできるようにエイリアスの中で見て使用する必要があります。このラインで

public IList<MyCustomClass> FindResults(FooBarTask st) 
{ 
    var typeConstructor = typeof(MyCustomClass).GetConstructors()[0]; 
    return DataAccess.Find<MyCustomClass>(DetachedCriteria.For<FooBarResult>() 
     .Add(Restrictions.Eq("Task", st)) 
     .SetProjection(
      Projections.ProjectionList() 
       .Add(Projections.Property("FieldOne"), "FieldOne") 
       .Add(Projections.Property("FieldTwo"), "FieldTwo")   
     ) 
     .SetResultTransformer(Transformers.AliasToBean(typeof(MyCustomClass))) 
     .List<MyCustomClass>() 
} 
関連する問題