2010-01-07 7 views
2

J'ai une classe de type MetadataRecord:NHibernate.Linq System.Nullable jette ArgumentException, la valeur "" est pas taper

public class MetadataRecord { 
    public virtual long? IntegerObject { get; set; } 
    public virtual string ClassName { get; set; } 
    public virtual DateTime? DateObject { get; set; } 
    public virtual double? DecimalObject { get; set; } 
    public virtual long MetadataId { get; set; } 
    public virtual long MetadataLabelId { get; set; } 
    public virtual long ObjectId { get; set; } 
    public virtual string StringObject { get; set; } 
    public virtual Asset Asset { get; set; } 
} 

et un fichier de mappage correspondant comme suit:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        assembly="ActiveMediaDataAccess" 
        namespace="ActiveMediaDataAccess.Entities"> 

    <class name="MetadataRecord" table="WM_META_DATA" lazy="true"> 
    <id name="MetadataId" column="META_DATA_ID"> 
     <generator class="seqhilo" /> 
    </id> 
    <property name="MetadataLabelId" column="META_DATA_LABEL_ID" /> 
    <property name="ObjectId" column="OBJECT_ID" /> 
    <property name="ClassName" column="CLASS_NAME" /> 
    <property name="IntegerObject" column="INTEGER_OBJECT" /> 
    <property name="DecimalObject" column="DECIMAL_OBJECT" /> 
    <property name="DateObject" column="DATE_OBJECT" /> 
    <property name="StringObject" column="STRING_OBJECT" /> 
    <many-to-one name="Asset" column="OBJECT_ID" not-null="true" /> 
    </class> 
</hibernate-mapping> 

I J'exécute un test unitaire contre cette classe pour vérifier les valeurs renvoyées pour IntegerObject qui est un type null de long, à partir d'une instance de MetadataRecord. J'utilise NHibernate.Linq (v 1.1.0.1001) de requête comme suit:

[TestMethod()] 
public void IntegerObjectTest() { 
    var integerObject = _sessionFactory.OpenSession().Linq<MetadataRecord>() 
             .Where(m => m.ObjectId == 65675L) 
             .Select(m => m.IntegerObject) 
             .FirstOrDefault(); 
    Assert.IsNull(integerObject); 
} 

La colonne INTEGER_OBJECT de la table correspondante est annulable, et je me attends IsNull est vrai ou faux. Cependant, je reçois l'erreur suivante:

Test method ActiveMediaMetadataViewerTestProject.MetadataRecordTest.IntegerObjectTest threw exception: NHibernate.Exceptions.GenericADOException: Unable to perform find[SQL: SQL not available] ---> System.ArgumentException: The value "" is not of type "System.Nullable`1[System.Int64]" and cannot be used in this generic collection. Parameter name: value.

Je ne peux pas comprendre pourquoi il essaie de lancer une chaîne à un type Nullable. Y a-t-il une autre façon d'ouvrir la session, de décorer la classe, de construire le fichier de mappage, où est-ce que je me trompe? Je pourrais avoir recours à des critères, mais j'ai beaucoup apprécié l'intellisense et la «refactorisation» avec Linq.

Répondre

1

meilleure solution (traduit SQL en tout):

[TestMethod()] 
public void IntegerObjectTest() { 
    var integerObject = _sessionFactory.OpenSession().Linq<MetadataRecord>() 
             .Where(m => m.ObjectId == 65675L) 
             .Select(m => new long?(m.IntegerObject))           
             .FirstOrDefault(); 
    Assert.IsNull(integerObject); 
} 
+0

Je n'ai pas travaillé sur ce projet depuis des années, mais le '' nouveau temps semble() comme le billet. Je suppose que cela fonctionne et est utile pour quelqu'un là-bas. Merci @RobertJ. – Lennox

1

Ma solution:

[TestMethod()] 
public void IntegerObjectTest() { 
    var integerObject = _sessionFactory.OpenSession().Linq<MetadataRecord>() 
             .Where(m => m.ObjectId == 65675L) 
             .Select(m => m.IntegerObject) 
             .AsEnumerable() 
             .FirstOrDefault(); 
    Assert.IsNull(integerObject); 
} 

Pour une raison quelconque, NHibernate.Linq n'aime pas appeler d'abord(), FirstOrDefault() (et je devine unique() et SingleOrDefault()) sur les types nullable, et renvoie l'erreur ci-dessus si le champ est null. Cela fonctionne correctement si le type nullable a réellement une valeur. Si je pousse les résultats dans une collection en mémoire via AsEnumerable(), ToArray(), ToList(), etc, alors il joue nice et retourne mon type nullable.