C# 使用QueryOver的联接中的FirstOrDefault

C# 使用QueryOver的联接中的FirstOrDefault,c#,nhibernate,C#,Nhibernate,首先,我是NHibernate的新手。我已经在很多页面上搜索了关于QueryOver的内容,但对我来说最有利可图的页面是。多亏了它,我想到了一个“半解决方案”,但我需要这个更好的解决方案 我有以下课程: public class Variable { public virtual int Id {get; set; } public virtual string Nombre { get; set; } public virtual string Descripcion

首先,我是NHibernate的新手。我已经在很多页面上搜索了关于QueryOver的内容,但对我来说最有利可图的页面是。多亏了它,我想到了一个“半解决方案”,但我需要这个更好的解决方案

我有以下课程:

public class Variable
{
    public virtual int Id {get; set; }
    public virtual string Nombre { get; set; }
    public virtual string Descripcion { get; set; }
    public virtual IList<ValorVariable> Valores { get; set; }
    public virtual bool Temporal { get; set; }
    public virtual bool Eliminado{ get; set; }
}

public class ValorVariable
{
    public virtual int Id {get; set; }
    public virtual int IdVariable { get; set; }
    public virtual Variable Variable { get; set; }
    public virtual DateTime FechaValor { get; set; }
    public virtual decimal Valor { get; set; }
}

public class VariableLigera
{
    public virtual int Id {get; set; }
    public string Nombre { get; set; }
    public string Descripcion { get; set; }
    public bool Temporal { get; set; }
    public Decimal Valor { get; set; }
}
公共类变量
{
公共虚拟整数Id{get;set;}
公共虚拟字符串Nombre{get;set;}
公共虚拟字符串描述符{get;set;}
公共虚拟IList值{get;set;}
公共虚拟布尔时态{get;set;}
公共虚拟布尔Eliminado{get;set;}
}
公共类变量
{
公共虚拟整数Id{get;set;}
公共虚拟int IdVariable{get;set;}
公共虚拟变量{get;set;}
公共虚拟日期时间{get;set;}
公共虚拟十进制值{get;set;}
}
公共类变量
{
公共虚拟整数Id{get;set;}
公共字符串Nombre{get;set;}
公共字符串描述符{get;set;}
公共布尔时态{get;set;}
公共十进制值{get;set;}
}
Variable是“重要”类,除其他外,它的IList为“ValorVariable”,有一个值(“Valor”)和一个值日期(“FechaValor”)。“VariableLigera”类似于一个“light”类的变量,它具有变量的一些属性和ValorVariable列表的一个值。我希望这是清楚的

为了填充VariableLigera,我正在尝试进行查询。我想这样做:

Variable variableAlias = null;
VariableLigera variableLigeraAlias = null;

var result = _session
            .QueryOver(() => variableAlias ).Where(x => x.Eliminado == false)
            .Select(
                Projections.Property(() => variableAlias .Id).WithAlias(() => variableLigeraAlias .Id),
                Projections.Property(() => variableAlias .Nombre).WithAlias(() => variableLigeraAlias .Nombre),
                Projections.Property(() => variableAlias .Descripcion).WithAlias(() => variableLigeraAlias .Descripcion),
                Projections.Property(() => variableAlias .Temporal).WithAlias(() => variableLigeraAlias .Temporal),
                Projections.Property(() => variableAlias .Valores.FirstOrDefault().Valor).WithAlias(() => variableLigeraAlias .Valor)
            )
            .TransformUsing(Transformers.AliasToBean<VariableLigera>())
            .List<VariableLigera>();
SELECT 
    /*Variable properties */
    (       
        SELECT 
            TOP(1) this_0_.Valor AS y0_ 
        FROM 
            ValorVariable this_0_ 
        WHERE 
            this_0_.VariableID = this_.ID
    ) AS y1_ 
FROM 
    Variable this_ 
WHERE 
    this_.Eliminado = 0
变量variableAlias=null;
VariableLigera variableLigeraAlias=null;
var result=\u会话
.QueryOver(()=>variableAlias)。其中(x=>x.Eliminado==false)
.选择(
properties(()=>variableAlias.Id).WithAlias(()=>VariableLigerAlias.Id),
Projections.Property(()=>variableAlias.Nombre).WithAlias(()=>VariableLigerAlias.Nombre),
Projections.Property(()=>variableAlias.Description).WithAlias(()=>VariableLigerAlias.Description),
Projections.Property(()=>variableAlias.Temporal).WithAlias(()=>VariableLigerAlias.Temporal),
Projections.Property(()=>variableAlias.Valores.FirstOrDefault().Valor).WithAlias(()=>VariableLigerAlias.Valor)
)
.TransformUsing(Transformers.AliasToBean())
.List();
这就是问题所在。我想在variableLigeraAlias的属性“Valor”中输入variableLigera的Valores列表的第一个或默认值。但它抛出了一个异常,“function FirstOrDefault not Recognited”

所以我尝试了另一件事,创建ValorVariable的别名并将其加入到查询中。像这样:

Variable variableAlias = null;
VariableLigera variableLigeraAlias = null;
ValorVariable valorVariableAlias = null;
var result = _session
            .QueryOver(() => variableAlias).Where(x => x.Eliminado == false)
            .JoinAlias(() => variableAlias.Valores, () => valorVariableAlias)
            .Select(
                Projections.Property(() => variableAlias.Id).WithAlias(() => variableLigeraAlias.Id),
                Projections.Property(() => variableAlias.Nombre).WithAlias(() => variableLigeraAlias.Nombre),
                Projections.Property(() => variableAlias.Descripcion).WithAlias(() => variableLigeraAlias.Descripcion),
                Projections.Property(() => variableAlias.Temporal).WithAlias(() => variableLigeraAlias.Temporal),
                Projections.Property(() => valorVariableAlias.Valor).WithAlias(() => variableLigeraAlias.Valor)
            )
            .TransformUsing(Transformers.AliasToBean<VariableLigera>())
            .List<VariableLigera>();
变量variableAlias=null;
VariableLigera variableLigeraAlias=null;
ValorVariable valorVariableAlias=null;
var result=\u会话
.QueryOver(()=>variableAlias)。其中(x=>x.Eliminado==false)
.JoinAlias(()=>variableAlias.Valores,()=>valorVariableAlias)
.选择(
properties(()=>variableAlias.Id).WithAlias(()=>VariableLigerAlias.Id),
Projections.Property(()=>variableAlias.Nombre).WithAlias(()=>VariableLigerAlias.Nombre),
Projections.Property(()=>variableAlias.Description).WithAlias(()=>VariableLigerAlias.Description),
Projections.Property(()=>variableAlias.Temporal).WithAlias(()=>VariableLigerAlias.Temporal),
Projections.Property(()=>valorVariableAlias.Valor).WithAlias(()=>VariableLigerAlias.Valor)
)
.TransformUsing(Transformers.AliasToBean())
.List();
通过这个查询,我得到了结果,但是我多次得到了每个变量(ValoresVariables列表中每个值都有一个副本)。例如,如果一个变量有3个值,查询将返回3个带有3个值的“VariablesLigera”,但我只想要一个带有其列表中第一个值的变量

简而言之,为了明确起见,我希望每个变量都有一个结果,值(“Valor”)列表中的firstordefault值。可以使用QueryOver吗?非常感谢


PS:因为英语不是我的母语,也许有些事情不太容易理解。如果有任何疑问,请随时询问。再次感谢。

如果我理解您的意思,
VariableLigera
正在充当实体
变量的DTO。您需要
变量
的大多数属性,以及
集合的一个值。 除非需要集合的任何值,否则需要指定选择第一个值的条件。因为
VariableValor
有一个日期属性,所以让我们使用它来选择最近的值

这里尝试使用子查询来实现这一点

未经测试的代码(它可以编译,但我没有执行它:

Variable variableAlias = null;
VariableLigera variableLigeraAlias = null;
ValorVariable valorVariableAlias = null;
var result = _session
        .QueryOver(() => variableAlias).Where(x => x.Eliminado == false)
        .JoinAlias(() => variableAlias.Valores, () => valorVariableAlias)
        .SelectList(projections => projections
            .Select(() => variableAlias.Id).WithAlias(() => variableLigeraAlias.Id),
            .Select(() => variableAlias.Nombre).WithAlias(() => variableLigeraAlias.Nombre),
            .Select(() => variableAlias.Descripcion).WithAlias(() => variableLigeraAlias.Descripcion),
            .Select(() => variableAlias.Temporal).WithAlias(() => variableLigeraAlias.Temporal),

            .SelectSubQuery(QueryOver.Of<ValorVariable>( () => valorVariableAlias)
                                .Where(vv => vv.IdVariable == variableAlias.Id)
            .Select(Projections.Max<ValorVariable>(vv => vv.FechaValor)))
                                .Select(Projections.Property(() => valorVariableAlias.Valor))
           .WithAlias(() => variableLigeraAlias.Valor)
        )
        .TransformUsing(Transformers.AliasToBean<VariableLigera>())
        .List<VariableLigera>();
变量variableAlias=null;
VariableLigera variableLigeraAlias=null;
ValorVariable valorVariableAlias=null;
var result=\u会话
.QueryOver(()=>variableAlias)。其中(x=>x.Eliminado==false)
.JoinAlias(()=>variableAlias.Valores,()=>valorVariableAlias)
.选择列表(投影=>projections
.选择(()=>variableAlias.Id).WithAlias(()=>VariableLigerAlias.Id),
.选择(()=>variableAlias.Nombre)。使用别名(()=>VariableLigerAlias.Nombre),
.选择(()=>variableAlias.Description)。使用别名(()=>VariableLigerAlias.Description),
.选择(()=>variableAlias.Temporal)。使用别名(()=>VariableLigerAlias.Temporal),
.SelectSubQuery(查询(()=>valorVariableAlias的版本)
.Where(vv=>vv.IdVariable==variableAlias.Id)
.Select(projects.Max(vv=>vv.FechaValor)))
.Select(projects.Property(()=>valorVariableAlias.Valor))
.WithAlias(()=>variableLige
SELECT 
    /*Variable properties */
    (       
        SELECT 
            TOP(1) this_0_.Valor AS y0_ 
        FROM 
            ValorVariable this_0_ 
        WHERE 
            this_0_.VariableID = this_.ID
    ) AS y1_ 
FROM 
    Variable this_ 
WHERE 
    this_.Eliminado = 0
QueryOver.Of<ValorVariable>()
    .Where(vv => vv.Variable.Id == variableAlias.Id)
    .Select(vv => vv.Valor)
    .OrderBy(vv => vv.FechaValor).Desc
    .Take(1)