2009-06-23 10 views
31

Ich verwende NHibernate und eine gespeicherte Prozedur über eine benannte Abfrage Aufruf:Wie können C# -Nullwerte typisierte Werte für NHibernate namens IQuery-Parameter festgelegt werden?

<sql-query name="SearchStuff" read-only="true" cacheable="true"> 
    <return class="ResultEntity" /> 
    EXEC [SearchStuff] ?, ?, ? </sql-query> 

Viele der Parameter für gespeicherte Prozeduren sind bewusst auf NULL festlegbaren - dies kann nicht geändert werden.

Die C#:

IQuery listQuery = this.Session.GetNamedQuery("SearchStuff"); 
listQuery.SetInt32(0, param1); 
listQuery.SetDateTime(1, param2); 
listQuery.SetString(2, param3); 
IList<ResultEntity> results = listQuery.List<ResultEntity>(); 

Leider NHibernate bietet keine SetXyz() Methoden für Nullable-Wertetypen so habe ich versucht, einige Erweiterungsmethoden Zugabe zu kompensieren:

public static class QueryExtensions 
{ 
    public static void SetInt32(this IQuery query, int position, int? val) 
    { 
     if (val.HasValue) 
     { 
      query.SetInt32(position, val.Value); 
     } 
     else 
     { 
      query.SetParameter(position, null); 
     } 
    } 

    public static void SetInt32(this IQuery query, string name, int? val) 
    { 
     if (val.HasValue) 
     { 
      query.SetInt32(name, val.Value); 
     } 
     else 
     { 
      query.SetParameter(name, null); 
     } 
    } 

    public static void SetDateTime(this IQuery query, int position, DateTime? val) 
    { 
     if (val.HasValue) 
     { 
      query.SetDateTime(position, val.Value); 
     } 
     else 
     { 
      query.SetParameter(position, null); 
     } 
    } 

    public static void SetDateTime(this IQuery query, string name, DateTime? val) 
    { 
     if (val.HasValue) 
     { 
      query.SetDateTime(name, val.Value); 
     } 
     else 
     { 
      query.SetParameter(name, null); 
     } 
    } 
} 

Ich habe versucht, verschiedene Versionen von diesen, aber keine funktionieren. Der Code nicht oben mit dem Fehler:

System.ArgumentNullException : A type specific Set(position, val) should be called because the Type can not be guessed from a null value. 

Ich versuchte auch nicht einfach die Parametereinstellung aber NHibernate erfordert jeden Parameter festgelegt werden. Ich habe versucht, beide positionelle und benannte Versionen mit den gleichen Ergebnissen zu verwenden.

Gibt es eine Möglichkeit NULL-Wert zu Wert typisierte Parameter in NHibernate benannten Abfragen zuweisen?

Antwort

50

In Ordnung, es gibt einige Überschreibungen auf SetParameter, mit denen der Typ explizit festgelegt werden kann. Zum Beispiel:

query.SetParameter(position, null, NHibernateUtil.Int32); 

Die vollständigen Erweiterungsmethoden (für Int32 und Datetime-only) sind jetzt:

public static class QueryExtensions 
{ 
    public static void SetInt32(this IQuery query, int position, int? val) 
    { 
     if (val.HasValue) 
     { 
      query.SetInt32(position, val.Value); 
     } 
     else 
     { 
      query.SetParameter(position, null, NHibernateUtil.Int32); 
     } 
    } 

    public static void SetInt32(this IQuery query, string name, int? val) 
    { 
     if (val.HasValue) 
     { 
      query.SetInt32(name, val.Value); 
     } 
     else 
     { 
      query.SetParameter(name, null, NHibernateUtil.Int32); 
     } 
    } 

    public static void SetDateTime(this IQuery query, int position, DateTime? val) 
    { 
     if (val.HasValue) 
     { 
      query.SetDateTime(position, val.Value); 
     } 
     else 
     { 
      query.SetParameter(position, null, NHibernateUtil.DateTime); 
     } 
    } 

    public static void SetDateTime(this IQuery query, string name, DateTime? val) 
    { 
     if (val.HasValue) 
     { 
      query.SetDateTime(name, val.Value); 
     } 
     else 
     { 
      query.SetParameter(name, null, NHibernateUtil.DateTime); 
     } 
    } 
} 
+0

Vielen Dank für das, hilf mir :) – RhysC

+3

Wenn Sie das Abfrageobjekt aus den Methoden geben Sie auch richtig, zum Beispiel erhalten die Verkettungs: public static IQuery SetDateTime (... ... retrun Abfrage; –

+0

Feste Erweiterungen ! –

3

Die vollständigen Erweiterungsmethoden (für Int32 und Datetime nur) mit Verkettungs sind jetzt:

public static class QueryExtensions 
{ 
    public static IQuery SetInt32(this IQuery __query, int __position, int? __val) 
    { 
     var _query = __val.HasValue ? __query.SetInt32(__position, __val.Value) : __query.SetParameter(__position, null, NHibernateUtil.Int32); 

     return _query; 
    } 

    public static IQuery SetInt32(this IQuery __query, string __name, int? __val) 
    { 
     var _query = __val.HasValue ? __query.SetInt32(__name, __val.Value) : __query.SetParameter(__name, null, NHibernateUtil.Int32); 

     return _query; 
    } 

    public static IQuery SetDateTime(this IQuery __query, int __position, DateTime? __val) 
    { 
     var _query = __val.HasValue ? __query.SetDateTime(__position, __val.Value) : __query.SetParameter(__position, null, NHibernateUtil.DateTime); 

     return _query; 
    } 

    public static IQuery SetDateTime(this IQuery __query, string __name, DateTime? __val) 
    { 
     var _query = __val.HasValue ? __query.SetDateTime(__name, __val.Value) : __query.SetParameter(__name, null, NHibernateUtil.DateTime); 

     return _query; 
    } 
} 
+0

Danke, rbrock, für diesen Zusatz zu den Erweiterungen oben.Das ist genau das, was ich brauchte :) –

10

Ein anderer Weg, es zu tun ist:

query.SetParameter<int?>(0, null); 
query.SetParameter<DateTime?>(1, null); 
... 

Und so weiter ...

Beachten Sie das ? Symbol, das den primitiven Typ Nullwert macht.

Verwandte Themen