我正在尝试从 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 和其他几个选项来拉回类别、库存和折扣金额。我已经通过这个查询使用 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 小数。我的目标是使用 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));
此查询仅拉回 Category 的 ID,虽然它确实拉回了完整的 Inventory 实体,但它使用完整的附加数据库查询来获取它。
...
.Select(Projections.Property(() => categoryAlias),
Projections.Property(() => inventoryAlias),
Projections.Property(() => discountAlias.DiscountAmount));
此查询引发“无法解析属性: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 查询。目前我正在使用一个 QueryOver 查询,它返回 Category 和 Inventory 实体的 ID,然后分别查询它们,但由于无论如何我必须在第一个查询中点击这些表,我宁愿一次性返回它们。
编辑 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 ...