カテゴリを共有する製品のリストを取得しようとしています。
Hibernate は間違った製品を返しません。
ここに私の基準APIメソッドがあります:
public IList<Product> GetProductForCategory(string name)
{
return _session.CreateCriteria(typeof(Product))
.CreateCriteria("Categories")
.Add(Restrictions.Eq("Name", name))
.List<Product>();
}
これが私のHQLメソッドです:
public IList<Product> GetProductForCategory(string name)
{
return _session.CreateQuery("select from Product p, p.Categories.elements c where c.Name = :name").SetString("name",name).List<Product>();
}
どちらのメソッドも、2 つの製品を返す必要がある場合に製品を返しません。
Product クラスのマッピングは次のとおりです。
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="CBL.CoderForTraders.DomainModel" namespace="CBL.CoderForTraders.DomainModel">
<class name="Product" table="Products" >
<id name="_persistenceId" column="ProductId" type="Guid" access="field" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="assigned" />
</id>
<version name="_persistenceVersion" column="RowVersion" access="field" type="int" unsaved-value="0" />
<property name="Name" column="ProductName" type="String" not-null="true"/>
<property name="Price" column="BasePrice" type="Decimal" not-null="true" />
<property name="IsTaxable" column="IsTaxable" type="Boolean" not-null="true" />
<property name="DefaultImage" column="DefaultImageFile" type="String"/>
<bag name="Descriptors" table="ProductDescriptors">
<key column="ProductId" foreign-key="FK_Product_Descriptors"/>
<one-to-many class="Descriptor"/>
</bag>
<bag name="Categories" table="Categories_Products" >
<key column="ProductId" foreign-key="FK_Products_Categories"/>
<many-to-many class="Category" column="CategoryId"></many-to-many>
</bag>
<bag name="Orders" generic="true" table="OrderProduct" >
<key column="ProductId" foreign-key="FK_Products_Orders"/>
<many-to-many column="OrderId" class="Order" />
</bag>
</class>
</hibernate-mapping>
最後に、Category クラスのマッピング:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="CBL.CoderForTraders.DomainModel" namespace="CBL.CoderForTraders.DomainModel" default-access="field.camelcase-underscore" default-lazy="true">
<class name="Category" table="Categories" >
<id name="_persistenceId" column="CategoryId" type="Guid" access="field" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="assigned" />
</id>
<version name="_persistenceVersion" column="RowVersion" access="field" type="int" unsaved-value="0" />
<property name="Name" column="Name" type="String" not-null="true"/>
<property name="IsDefault" column="IsDefault" type="Boolean" not-null="true" />
<property name="Description" column="Description" type="String" not-null="true" />
<many-to-one name="Parent" column="ParentID"></many-to-one>
<bag name="SubCategories" inverse="true">
<key column="ParentID" foreign-key="FK_Category_ParentCategory" />
<one-to-many class="Category"/>
</bag>
<bag name="Products" table="Categories_Products">
<key column="CategoryId" foreign-key="FK_Categories_Products" />
<many-to-many column="ProductId" class="Product"></many-to-many>
</bag>
</class>
</hibernate-mapping>
何が問題なのか分かりますか?
add 行を削除すると、クエリは次のようになります。
return _session.CreateCriteria(typeof(Product))
.CreateCriteria("Categories")
.List<Product>();
ウォッチ ウィンドウを見ると、カテゴリが関連付けられた 5 つの製品が返されます。最初のクエリで探しているカテゴリの名前が 2 つの製品に表示されます。
したがって、行を追加すると何か問題があります: .Add(Restrictions.Eq("Name", name))
制限行を含む生成された SQL を次に示します。
NHibernate: this_.ProductId を ProductId23_1_ として、this_.RowVersion を RowVersion23_1_ として、this_.ProductName を ProductN3_23_1_ として、this_.BasePrice を BasePrice23_1_ として、this_.IsTaxable を IsTaxable23_1_ として、this_.DefaultImageFile を DefaultI6_23_1_ として、categories3_.ProductId を ProductId として、category1_.CategoryId を CategoryId として選択します。 、category1_.CategoryId を CategoryId16_0_ として、category1_.RowVersion を RowVersion16_0_ として、category1_.Name を Name16_0_ として、category1_.IsDefault を IsDefault16_0_ として、category1_.Description を Descript5_16_0_ として、category1_.ParentID を ParentID16_0_ として。 ProductId 内部結合 Categoriescategory1_ on Categories3_.CategoryId=category1_.CategoryId WHERE category1_.Name = @p0; @p0 = 'モメンタム'