NHibernate.Linq System.Nullable генерирует ArgumentException, значение "" не является типом - PullRequest
2 голосов
/ 07 января 2010

У меня есть класс типа 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>

Я запускаю модульный тест для этого класса, чтобы проверить значения, возвращаемые для IntegerObject, который имеет тип null, из экземпляра MetadataRecord. Я использую 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 из соответствующей таблицы имеет значение NULL, и я ожидаю, что IsNull будет истинным или ложным. Однако я получаю следующую ошибку:

Метод тестирования ActiveMediaMetadataViewerTestProject.MetadataRecordTest.IntegerObjectTest вызвал исключение: NHibernate.Exceptions.GenericADOException: невозможно выполнить поиск [SQL: SQL недоступен] ---> System.ArgumentException: значение «» не относится к типу «SystemN `1 [System.Int64]" и не может использоваться в этой универсальной коллекции. Имя параметра: значение.

Я не могу понять, почему он пытается привести строку к обнуляемому типу. Есть ли другой способ, которым я должен открывать сессию, украшать класс, даже создавать файл сопоставления, ..... где я здесь ошибаюсь? Я мог бы прибегнуть к использованию Criteria, но я очень наслаждался интеллигентностью и «рефакторизацией» с Linq.

Ответы [ 2 ]

1 голос
/ 23 ноября 2015

Лучшее решение (полностью переведено на 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); 
} 
1 голос
/ 11 января 2010

Мой обходной путь:

[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. Это прекрасно работает, если тип null-типа имеет значение. Если я помещаю результаты в коллекцию в памяти с помощью AsEnumerable (), ToArray (), ToList () и т. Д., То он воспроизводится хорошо и возвращает мой тип, допускающий значение NULL.

...