2

タイプ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のインスタンスからnull許容型のlongであるIntegerObjectに対して返される値を確認しています。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がtrueまたはfalseであると予想します。ただし、次のエラーが発生します。

テストメソッドActiveMediaMetadataViewerTestProject.MetadataRecordTest.IntegerObjectTestが例外をスローしました:NHibernate.Exceptions.GenericADOException:find [SQL:SQL not available] ---> System.ArgumentException:値""はタイプ"System.Nullable`1[ではありませんSystem.Int64] "であり、この汎用コレクションでは使用できません。パラメータ名:値。

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.

4

2 に答える 2

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はnull許容型でFirst()、FirstOrDefault()を呼び出すのが好きではなく(そして私はSingle()とSingleOrDefault()を推測しています)、フィールドがnullの場合は上記のエラーをスローします。null許容型に実際に値がある場合は正常に機能します。AsEnumerable()、ToArray()、ToList()などを介して結果をメモリ内コレクションにプッシュすると、正常に再生され、null許容型が返されます。

于 2010-01-11T18:28:14.090 に答える
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); 
} 
于 2015-11-23T14:03:38.153 に答える