views:

393

answers:

1

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  A: 

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.

Lennox