使用DetachedCriteria(prefereable)或QueryOver从Tables(Using Inner Join)中获取列

时间:2016-08-08 03:37:39

标签: c# sql-server nhibernate fluent-nhibernate queryover

我在使用DetachedCriteria(或使用Session QueryOver)的NHibernate中遇到问题。我需要从每个表中只获得几列,如下面的类:

public class PanelaCorrida : BaseEntity
{
    public virtual Int64? CodCorrida { get; set; }

    public virtual Int64 NumLocal { get; set; }

    public virtual Boolean IdcInspecionada { get; set; }

    public virtual String Sigla { get; set; }

    public virtual String Rota { get; set; }

    public virtual Local Local { get; set; }

    public virtual Panela Panela { get; set; }
}


public class Panela : BaseEntity
{
    public Panela()
    {
        this.Local = new Local();
        this.PanelaCorridas = new List<PanelaCorrida>();
    }

    public virtual Int32 Numero { get; set; }

    public virtual Boolean IdcAtiva { get; set; }

    public virtual Int16 Status { get; set; }

    public virtual ICollection<PanelaCorrida> PanelaCorridas { get; set; }

    public virtual Local Local { get; set; }

    #endregion
}


public class Local : BaseEntity
{
    public Local()
    {
        this.PanelaCorridas = new List<PanelaCorrida>();
        this.Panelas = new List<Panela>();
    }

    #region Property

    public virtual Int32 IdLocal { get; set; }

    public virtual Int32 AreaLocal { get; set; }

    public virtual String Descricao { get; set; }

    public virtual String Codigo { get; set; }

    #endregion
}

基本上,实体'Panela'是'PanelaCorrida'的母亲(每个Panela可以有多个PanelaCorrida)但是'PanelaCorrida'可以在一个Local中。但是一个当地人也可以拥有多个PanelaCorrida。基本上,这种关系:

Panela 1 - N PanelaCorrida

本地1 - N Panela

本地1 - N PanelaCorrida

对于这个查询,我需要获取db的Last PanelaCorrida,但我也需要Panela和Local的信息。

到目前为止,我可以使用这个NHibernate查询获取所有数据:

获取有效的'panela'的所有ID:

var panelaIdList = Session.QueryOver<Panela>()
                    .Select(c => c.Id)
                    .Where(c => c.IdcAtiva == true)
                    .List<Int64>();

获取活跃的'PanelaCorrida'的最后一个ID(以及最后生成的PanelaCorrida):

var corridaPanelaIdList = Session.QueryOver<PanelaCorrida>()
    .Select(
    Projections.Max<PanelaCorrida>(x => x.Id),
    Projections.Group<PanelaCorrida>(x => x.Panela)
    )
    .Where(p => p.Panela.IsIn(panelaIdList.ToArray()))
    .List<Object[]>();

现在,要获得包含所有这些表的所有信息的结果:

使用DetachedCriteria:

criteria = DetachedCriteria.For<PanelaCorrida>()
    .CreateAlias("Local", "L")
    .CreateAlias("Panela", "P")
    .Add(Restrictions.In("Id", corridaPanelaIdList.Select(x => x[0]).ToArray()));

使用Session QueryOver:

var corridas = Session.QueryOver<PanelaCorrida>()
    .Where(p => p.Id.IsIn(corridaPanelaIdList.Select(x => x[0]).ToArray()))
    .List<PanelaCorrida>();

但问题是,我只需要每个表的几列。使用NHibernate,我尝试过使用Projections,使用QueryOver,我尝试使用SelectList,但每次生成错误(无法找到...的属性)或者它们不会在结果中填充实体。

我怎么能做到这一点?

注意:这是我的查询(在SQL中):

select cd.num_panela_corrida, cd.num_panela, p.numero, l.num_local from scp_panela_corrida cd  
inner join scp_panela p on p.num_panela = cd.num_panela 
inner join scp_local l on l.num_local = cd.num_local and cd.num_panela_corrida
in (
    select 
        max( c.num_panela_corrida) as num_panela_corrida 
    from 
        scp_panela_corrida c 
    inner join
        scp_panela p on p.num_panela = c.num_panela
        and p.num_panela in (
            select 
                num_panela 
            from 
                scp_panela 
            where 
                idc_ativa = 1
        ) group by c.num_panela ) order by cd.num_panela_corrida desc

但是客户端不想使用存储过程或HQL。

欢迎任何帮助。

1 个答案:

答案 0 :(得分:1)

解决了以下代码(随Radim Kohler的链接提供)。

Radim,如果你愿意,请用提供的链接回答这个问题,我会接受它作为答案。谢谢你的帮助。

Panela panela = null;
Local local = null;

var query = session.QueryOver<PanelaCorrida>()
    .JoinAlias(c => c.Panela, () => panela)
    .Where (c => c.Id.IsIn(corridaPanelaIdList.ToArray()))
    .SelectList(list => list
    .Select(c => c.Id))
    .Select(c => c.CodCorrida)
    .Select(Projections.Property(() => panela.Id).As("Panela.Id"))
    .Select(Projections.Property(() => panela.IdcAtiva).As("Panela.IdcAtiva"))
    .TransformUsing(Transformers.AliasToBean(typeof(PanelaCorrida)));

不知道是否是最好的方法,但它有效。我们将使用QueryOver / DetachedCriteria分析最佳方法,但是现在,这非常有效。

注意:我删除了一些列,只是为了解释它是如何工作的。

再次感谢。