c# - NHibernate 使用 QueryOver 选择具有相关子对象的对象列表

标签 c# nhibernate queryover

我在处理一些可能非常简单的事情时遇到了麻烦。 在我的数据库中,我有以下表格:

tblOrder
-----------------
Id
OrderStatusId

tblOrderStatus
-----------------
Id
Name

我在我的项目中做了以下映射:

[Class(NameType = typeof(Order), Table = "tblOrder")
public class Order {
    [Id(-2, Name = "Id")]
    [Generator(-1, Class = "native")]
    public virtual long Id { get; set; }

    [ManyToOne]
    public virtual OrderStatus Status { get; set; }
}

[Class(NameType = typeof(OrderStatus), Table = "tblOrderStatus")]
public class OrderStatus {
    [Id(-2, Name = "Id")]
    [Generator(-1, Class = "native")]
    public virtual long Id { get; set; }

    [Property]
    public virtual string Name { get; set; }
}

查询应返回 IList<OrderSummary> 。我要类(class)OrderSummary拥有特性Status哪里Status是一个带有 Id 的对象和一个 Name属性(property)。这可以是 KeyValuePair或类型 OrderStatus (以最好且有效的为准)。获取订单不是问题,但添加 OrderStatus作为具有上述属性的对象是我遇到麻烦的部分。 我还需要将查询结果作为 JSON 返回给客户端。

OrderSummary应该看起来像这样:

public class OrderSummary {
    public long Id { get; set; }
    public OrderStatus Status { get; set; }
}

在我的第一个版本中OrderSummary OrderStatusId 有单独的属性和OrderStatusName 。这是可行的,但我试图避免这些单独的属性。 我也尝试过 SelectSubQuery但这会返回一个错误,因为它在子查询中返回多个字段。

------------------------------------------------ 更新 ----------- ------------------

按照 Fredy Treboux 的建议,我使用 Eager 更改了查询这会导致以下查询:

var query = session.QueryOver<OrderStatus>
    .Fetch(o => o.Status).Eager
    .JoinAlias(o => o.Status, () => statusAlias, JoinType.LeftOuterJoin);

我发现问题不是选择数据,而是如何转换检索到的 Status并将其分配给 OrderSummary.Status?我尝试过以下方法:

OrderSummary orderAlias = null;
query.SelectList(list => list
    .Select(o => o.Id).WithAlias(() => orderAlias.Id)
    .Select(() => statusAlias).WithAlias(() => orderAlias.Status)
).TransformUsing(Transformer.AliasToBean<OrderSummary>());

-------------------------------- 答案 -------------- --------------------

正如我在上次编辑中所说,问题似乎并不是 OrderStatus 的实际选择。但将其返回给客户。所以我认为这是我对 NHibernate 缺乏了解,相反,它就像添加 [JsonObject] 一样简单。属性为OrderStatus类(class)。我真是太傻了。

我已将查询更改为以下内容:

Order orderAlias = null;
OrderSummary orderSummary = null;
OrderStatus statusAlias = null;
var query = session.QueryOver<Order>(() => orderAlias)
    .JoinAlias(() => orderAlias.Status, () => statusAlias, JoinType.LeftOuterJoin);

query = query
    .Select(
        Projections.ProjectionList()
            .Add(Projections.Property(() => orderAlias.Id).WithAlias(() => orderSummary.Id))
            .Add(Projections.Property(() => orderAlias.Status).WithAlias(() => orderSummary.Status)
    );
Result = query.TransformUsing(Tranformers.AliasToBean<OrderSummary>())
    .List<OrderSummary>()
    .ToList();

最佳答案

恐怕目前还不可能。我猜想 Nhibernate 转换器无法构造嵌套的复杂属性。 您可以返回元组列表,然后手动将其强制转换为您的实体:

OrderStatus statusAlias = null;        

var tuples = Session.QueryOver<Order>()
            .JoinQueryOver(x => x.Status, () => statusAlias)
            .SelectList(list => list
                .Select(x => x.Id)
                .Select(x => statusAlias.Id)
                .Select(x => statusAlias.Name))
            .List<object[]>();

var result = tuples.Select(Convert);

private OrderSummary Convert(object[] item) {
            return new OrderSummary
            {
                Id = (long)item[0],
                OrderStatus = new OrderStatus { Id = (long)item[1], Name = (string)item[2] }
            };
        }

此外,如果您不太关心性能,则可以获取订单列表并将其转换为 OrderSummary。您可以通过简单地定义强制转换运算符或使用类似 AutoMapper 的工具来完成此操作。或ExpressMapper

关于c# - NHibernate 使用 QueryOver 选择具有相关子对象的对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44152318/

相关文章:

nhibernate - 将多个鉴别器值映射到 NHibernate 中的单个默认类

c# - 使用 DefaultCascade.All() 将实体添加到列表时,Nhibernate 不会设置 Id

c# - 带表达式树的 nhibernate queryover LIKE

c# - 如何从 WebApi 操作返回 html 页面?

c# - 如何为所有其他运行时错误添加通用错误页面?

mysql - 在 FROM 中使用子查询进行 HQL

c# - 简单 QueryOver : Unrecognised method call

c# - 健壮的 .NET 序列化的最佳方法

c# - 如何向私有(private)构造函数注入(inject)依赖?

NHibernate QueryOver with MaxResult, Group By 和 Order By