我在使用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。
欢迎任何帮助。
答案 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分析最佳方法,但是现在,这非常有效。
注意:我删除了一些列,只是为了解释它是如何工作的。
再次感谢。