QueryOver:从子查询中选择列
本文关键字:选择 查询 QueryOver | 更新日期: 2023-09-27 18:25:43
如何从不同表的子查询中选择/投影值到主查询中?
我有一个NH模型,像这样:
[Serializable]
public class MyModel
{
public virtual int Id {get; set;}
//more mapped values
....
//unmapped values
public virtual string ValueFromOtherTable {get;set;}
}
我想用这样的左联接来填充ValueFromOtherTable:
Select mt.*, ..., ot.ValueFromOtherTable from MyModelTable mt left
join OtherTable ot ON (somecondition)
其中MyModelTable是映射到MyModel类的表。我想通过从mt中选择所有值(填充NH映射的列)来填充ValueFromOtherTable(无NH映射),然后通过使用OtherTable来填充ValuefroOtherTable。
我无法通过QueryOver
连接两个表,因为模型中不存在直接的父子关系,所以JoinAlias
或JoinQueryOver
不起作用。我的MainQueryOver
查询MyModelTable
。
替代方案:
另一种选择是首先从MyModelTable中获取所有值,然后使用那里的属性查询OtherTable。然而,这将导致SELECT N+1
问题(对于MyModel
中的每个模型,选择一些OtherTable…),并使代码变得非常复杂。
有没有一个好的方法来解决这个问题,或者是通过使用所描述的替代方案来填充MyModel的唯一方法?
一种方法是使用Projections、Subquery和DTO。假设我们有DTO(与MyModel几乎相同,但有新的外部属性…例如Count)。然后我们可以这样做:
MyModel main = null;
MyModelDTO dto = null;
// the main query
var query = session.QueryOver<MyModel>(() => main);
// the subquery used for projection
var subquery = QueryOver.Of<OtherModel>()
// select something, e.g. count of the ID
.SelectList(selectGroup => selectGroup.SelectCount(o => o.ID))
// some condition
// kind of JOIN inside of the subquery
.Where(o => o.xxx == main.yyy); // just example
// now select the properties from main MyModel and one from the subquery
query.SelectList(sl => sl
.SelectSubQuery(subquery)
.WithAlias(() => dto.Count)
.Select(() => main.ID)
.WithAlias(() => dto .ID)
....
);
// we have to use transformer
query.TransformUsing(Transformers.AliasToBean<MyModelDTO >())
// and we can get a list of DTO
var list = query.List<MyModelDTO>();