NHibernate.Linq System.Nullable抛出ArgumentException,值“”不是类型

时间:2010-01-07 19:23:31

标签: nhibernate linq-to-nhibernate

我有一个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; }
}

和匹配的映射文件如下:

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

我正在对这个类运行一个单元测试,以检查从MetadataRecord实例中为IntegerObject返回的值,这是一个可以为null的long类型。我正在使用NHibernate.Linq(v 1.1.0.1001)进行查询,如下所示:

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

相应表中的INTEGER_OBJECT列可以为空,我希望IsNull为true或false。但是,我收到以下错误:

  

测试方法ActiveMediaMetadataViewerTestProject.MetadataRecordTest.IntegerObjectTest抛出异常:NHibernate.Exceptions.GenericADOException:无法执行find [SQL:SQL not available] ---&gt; System.ArgumentException:值“”不是“System.Nullable .1 [System.Int64]”类型,不能在此通用集合中使用。   参数名称:value。

我无法弄清楚为什么它试图将字符串转换为可空类型。有没有其他方式我应该打开会话,装饰类,甚至构建映射文件,.....我在哪里错了?我可以使用Criteria,但我非常喜欢与Linq的intellisense和“可重构性”。

1 个答案:

答案 0 :(得分:1)

我的解决方法:

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

出于某种原因,NHibernate.Linq不喜欢在可空类型上调用First(),FirstOrDefault()(我猜测Single()和SingleOrDefault()),如果该字段为null则抛出上述错误。如果可空类型实际上具有值,则它可以正常工作。如果我通过AsEnumerable(),ToArray(),ToList()等将结果推送到内存中的集合,那么它会很好地返回我的可空类型。