NHibernate.Linq System.Nullable getta ArgumentException, il valore “” non è di tipo

StackOverflow https://stackoverflow.com/questions/2023010

  •  19-09-2019
  •  | 
  •  

Domanda

Ho una classe di tipo MetadataRecord:

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

e un file di mapping corrispondente come segue:

<?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>

Sono in esecuzione di un test di unità contro questa classe per verificare la presenza di valori restituiti per IntegerObject che è un tipo nullable di tempo, da un'istanza di MetadataRecord. Sto usando NHibernate.Linq (v 1.1.0.1001) per interrogare nel seguente modo:

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

La colonna INTEGER_OBJECT dalla tabella corrispondente è annullabile, e mi aspetto IsNull sia vero o falso. Tuttavia, ottengo il seguente errore:

  

Metodo di prova ActiveMediaMetadataViewerTestProject.MetadataRecordTest.IntegerObjectTest ha gettato un'eccezione: NHibernate.Exceptions.GenericADOException: Impossibile eseguire trovare [SQL: SQL non disponibile] ---> System.ArgumentException: Il valore "" non è di tipo "System.Nullable `1 [System.Int64]" e non può essere utilizzato in questa raccolta generica.   Nome di parametro:. Valore

Non riesco a capire perché si sta cercando di lanciare una stringa in un tipo nullable. C'è un altro modo in cui dovrei essere aprendo la sessione, decorando la classe, anche la costruzione del file di mapping, ..... dove sto andando male qui? Potrei ricorrere all'utilizzo di criteri, ma ero molto godendo l'intellisense e "refactorability" con LINQ.

È stato utile?

Soluzione

Una migliore soluzione (tradotto a SQL in tutto):

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

Altri suggerimenti

La mia soluzione:

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

Per qualche ragione, NHibernate.Linq non piace chiamare First (), FirstOrDefault () (e sto cercando di indovinare singola () e SingleOrDefault ()) per i tipi nullable, e getta l'errore precedente se il campo è nullo. E funziona bene se il tipo nullable in realtà ha un valore. Se spingo i risultati in una collezione in memoria tramite AsEnumerable (), ToArray (), ToList (), ecc, allora gioca bello e restituisce il mio tipo nullable.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top