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连接两个表,因为模型中不存在直接的父子关系,所以JoinAliasJoinQueryOver不起作用。我的MainQueryOver查询MyModelTable

替代方案:

另一种选择是首先从MyModelTable中获取所有值,然后使用那里的属性查询OtherTable。然而,这将导致SELECT N+1问题(对于MyModel中的每个模型,选择一些OtherTable…),并使代码变得非常复杂。

有没有一个好的方法来解决这个问题,或者是通过使用所描述的替代方案来填充MyModel的唯一方法?

QueryOver:从子查询中选择列

一种方法是使用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>();