2017-10-26 4 views
0

Ich habe vor kurzem eine sehr ähnliche Frage gestellt, aber während der Titel die Klassen erwähnte, bezog sich mein Inhalt meistens auf ein Tupel, und die (wirklich großartige) Antwort spiegelte das wider. Wenn ich versucht habe, eine Klasse für das Tupel zu ersetzen, bekomme ich TargetParameterCountException: Parameter count mismatch. Ausnahme.Wie kann ich NHibernate zu einer benutzerdefinierten Klasse zuordnen?

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


ich die folgende Methode habe eine Liste von Ergebnissen aus der Datenbank zu erhalten.

public static IList<T> Find<T>(DetachedCriteria crit) where T : class 
{ 
    lock (_locker) 
    { 
     return crit.GetExecutableCriteria(InstanceSession) 
      .List<T>(); 
    } 
} 

Dies funktioniert im Allgemeinen gut. Ich habe jedoch eine Methode geändert, die obige Methode aufruft.

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

Welche, auf das funktioniert (wie ich will nicht die ganze FooBarResult, nur bestimmte Spalten darauf zurück).

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

Und das ist die Klasse.

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

Wie bereits erwähnt, wenn der return crit.GetExecutableCriteria(InstanceSession).List<T>(); Code ausgeführt erhalte ich eine TargetParameterCountException: Parameter count mismatch. Ausnahme.

Gibt es eine Möglichkeit, ich kann es eine Liste meiner MyCustomClass zurückgeben?

Antwort

1

In dieser Zeile:

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

Sie erhalten die Erstens stimmt der Standardkonstruktor und seine Signatur offensichtlich nicht überein. Die einfachste Lösung für Ihren Fall ist:

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

Aber die sauberste Lösung wäre etwas in diese Richtung (ungetestet und auch ein wenig vereinfacht) sein:

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

Thank you so viel wieder, Ihre Hilfe wurde unschätzbar :) –

1

ich nicht getestet haben, aber Sie sollten Transformers.AliasToBean werfen Sie einen Blick in den Aliasnamen verwenden, um den Transformator arbeiten zu lassen:

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>() 
} 
Verwandte Themen