1

QueryOver クエリから複数のエンティティを返そうとしています。このコードはプレーン テキスト エディターで作成しているため、構文エラーが発生する可能性がありますが、アイデアは理解できるはずです。

public class Product
{
    public virtual int ID { get; set; }
    public virtual string ProductName { get; set; }
    public virtual List<Category> Categories { get; set; }
    public virtual List<Inventory> Inventories { get; set; }
    ...
}

public class Category
{
    public virtual int ID { get; set; }
    public virtual string CategoryName { get; set; }
    public virtual string Style { get; set; }
    public virtual Product Product { get; set; }
    ...
}

public class Inventory
{
    public virtual int ID { get; set; }
    public virtual List<Discount> Discounts { get; set; }
    public virtual Product Product { get; set; }
    public virtual bool InStock { get; set; }
    ...
}

public class Discount
{
    public virtual int ID { get; set; }
    public virtual Inventory Inventory { get; set; }
    public virtual decimal DiscountAmount { get; set; }
    ...
}

ここでの目標は、製品 ID と他のいくつかのオプションを使用して、1 つのクエリでカテゴリ、在庫、および割引金額を取得することです。このクエリで HQL を使用してこれを機能させることができました。

var query = session.CreateQuery("select category, inventory, discount.DiscountAmount"
    + " from Product product"
    + " join product.Categories category"
    + " join product.Inventories inventory"
    + " left join inventory.Discounts discount"
    + " where product.ID = :productID"
    + " and category.Style = :style"
    + " and inventory.InStock = 1");

このクエリを使用して、それぞれが Category エンティティ、Inventory エンティティ、および DiscountAmount 10 進数を持つオブジェクト配列のリストを取得します。私の目標は、QueryOver クエリを使用して、マジック ストリングを使用せずに同じクエリを実行することですが、うまくいきません。これが私がこれまでに試したことです:

Product productAlias = null;
Category categoryAlias = null;
...
var query = session.QueryOver<Product>(() => productAlias)
    .Where(() => productAlias.ID == productID)
    .JoinAlias(() => productAlias.Categories, () => categoryAlias)
    ...
    .Select(Projections.Property(() => categoryAlias.ID),
        Projections.Property(() => discountAlias.Inventory),
        Projections.Property(() => discount.DiscountAmount));

このクエリは、カテゴリの ID のみをプルバックし、完全なインベントリ エンティティをプルバックしますが、追加の完全なデータベース クエリを使用してそれを取得します。

    ...
    .Select(Projections.Property(() => categoryAlias),
        Projections.Property(() => inventoryAlias),
        Projections.Property(() => discountAlias.DiscountAmount));

このクエリは、"Could not resolve property: categoryAlias of : Product" の実行時例外をスローします。

    ...
    .Select(Projections.Property(() => categoryAlias.ID).WithAlias(() => ReturnClass.Category),
        Projections.Property(() => inventoryAlias.ID).WithAlias(() => ReturnClass.Inventory),
        Projections.Property(() => discountAlias.DiscountAmount).WithAlias(() => ReturnClass.DiscountAmount))
    .TransformUsing(Transformers.AliasToBean<ReturnClass>());

このクエリは、「Int32 型のオブジェクトは Category 型に変換できません」という実行時例外をスローします。

    ...
    .Select(Projections.Property(() => categoryAlias.ID)
    .TransformUsing(Transformers.AliasToBean<Category>())

このクエリは、既定のカテゴリ エンティティを返します。

では、QueryOver API を使用して HQL クエリを模倣する方法はありますか? それとも、HQL を選択するか複数のクエリを作成するかを選択する唯一のオプションですか?

編集:より明確にするために、私は本当に魔法の文字列をできるだけ避けたいので、強く型付けされた QueryOver クエリを本当に好みます。現在、Category エンティティと Inventory エンティティの ID を返す QueryOver クエリを使用してから、それらを個別にクエリしていますが、とにかく最初のクエリでこれらのテーブルをヒットする必要があるため、一度にすべてを返したいと思います。

編集2:私が達成しようとしている正確なSQLは

Select Category.ID, Category.CategoryName, Category.Style, (other Category columns),
Inventory.ID, Inventory.InStock, (other Inventory columns),
Discount.DiscountAmount
From Products as Product
Inner join Categories as Category ...
Where Product.ID = @productID
And Category.Style = @style
And ...
4

2 に答える 2

0

JoinAlias の代わりに Fetch を使用する必要があると思います。

.Fetch(product => product.Categories).Eager

select: // は使用しないでください。.List<Product>()// LINQ を使用すると、製品からカテゴリと在庫を取得できます。

于 2012-04-17T08:31:09.437 に答える
0

これは、私のカテゴリのすべてのサブカテゴリを「積極的に」ロードする例です。カテゴリ コレクションを反復処理するときに N+1 はありません。ここで鍵となるのは未来です。

Category catalias = null;


        var subCategories =_session.QueryOver<Category>().JoinQueryOver(x => x.SubCategories, () => catalias, JoinType.LeftOuterJoin).
            Future<Category>();

        var categories = _session.QueryOver<Category>().Where(x => x.ParentCategoryId == null).Future<Category>();
于 2012-04-19T17:37:35.403 に答える