NHibernate.Linq System.Nullable throws ArgumentException, the value “” is not type

天涯浪子 提交于 2019-12-12 18:20:56

问题


I have a class of type 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; }
}

and a matching mapping file as follows:

<?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'm running a unit test against this class to check for values returned for IntegerObject which is a nullable type of long, from an instance of MetadataRecord. I'm using NHibernate.Linq (v 1.1.0.1001) to query as follows:

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

The INTEGER_OBJECT column from the corresponding table is nullable, and I expect IsNull to be true or false. However, I get the following error:

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.

I can't figure out why it's trying to cast a string to a nullable type. Is there another way in which I should be opening the session, decorating the class, even constructing the mapping file, ..... where am I going wrong here? I could resort to using Criteria, but I was much enjoying the intellisense and "refactorability" with Linq.


回答1:


Better solution (translated to SQL in whole):

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



回答2:


My workaround:

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

For some reason, NHibernate.Linq does not like calling First(), FirstOrDefault() (and I'm guessing Single() and SingleOrDefault()) on nullable types, and throws the above error if the field is null. It works fine if the nullable type actually has a value. If I push the results into an in-memory collection via AsEnumerable(), ToArray(), ToList(), etc, then it plays nice and returns my nullable type.



来源:https://stackoverflow.com/questions/2023010/nhibernate-linq-system-nullable-throws-argumentexception-the-value-is-not-ty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!