【问题标题】:NHibernate.Linq System.Nullable throws ArgumentException, the value "" is not typeNHibernate.Linq System.Nullable 抛出 ArgumentException,值“”不是类型
【发布时间】:2010-01-07 19:23:31
【问题描述】:

我有一个 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 的值,它是一个可以为空的 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 为真或假。但是,我收到以下错误:

测试方法 ActiveMediaMetadataViewerTestProject.MetadataRecordTest.IntegerObjectTest 抛出异常:NHibernate.Exceptions.GenericADOException:无法执行查找[SQL:SQL 不可用] ---> System.ArgumentException:值“”不是“System.Nullable”类型`1[System.Int64]" 并且不能在此通用集合中使用。 参数名称:值。

我不明白为什么它试图将字符串转换为可为空的类型。还有另一种我应该打开会话,装饰类,甚至构建映射文件的方法,......我在哪里出错了?我可以使用 Criteria,但我非常喜欢 Linq 的智能感知和“可重构性”。

【问题讨论】:

    标签: nhibernate linq-to-nhibernate


    【解决方案1】:

    更好的解决方案(整体翻译成SQL):

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

    【讨论】:

    • 我已经很多年没有从事这个项目了,但是new long?() 看起来像门票。我假设这可行,并且对那里的人有帮助。谢谢@RobertJ。
    【解决方案2】:

    我的解决方法:

    [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()),如果字段为空,则会引发上述错误。如果可空类型实际上具有值,则它可以正常工作。如果我通过 AsEnumerable()、ToArray()、ToList() 等将结果推送到内存中的集合中,那么它会运行良好并返回我的可为空类型。

    【讨论】:

      猜你喜欢
      • 2021-07-11
      • 2012-08-10
      • 2018-11-11
      • 1970-01-01
      • 1970-01-01
      • 2019-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多