我在处理一些可能非常简单的事情时遇到了麻烦。 在我的数据库中,我有以下表格:
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/