【问题标题】:Variable of type referenced from scope, but it is not defined. Error to compare string in QueryOver从范围引用的类型变量,但未定义。在 QueryOver 中比较字符串时出错
【发布时间】:2024-05-01 16:35:02
【问题描述】:

是的,我知道在 * 中有很多关于这个主题的问题开放和回答,但没有一个解决我的问题。

我正在尝试比较 QueryOver 的 where 子句中的两个字符串,但出现错误“从范围 '' 引用的 '' 类型的变量 '',但未定义”。我不知道我做错了什么,也没有找到适合我的案例的例子。谁能帮帮我?

这是我的代码:

var queryOverPaciente = _session.QueryOver(() => pacienteAlias).
    Where(() => pacienteAlias.DataCadastro.Value.IsBetween(dataInicio).And(dataFinal));


// Other things....

// the error occurs here. "Identificacao" and "MatriculaInicio" are strings 
// and I want to select all registers that "Identificacao" >= "MatriculaInicio".

queryOverPaciente = queryOverPaciente.Where(p => 
     p.Identificacao.CompareTo(filtroRelatorio.MatriculaInicio) >= 0);

【问题讨论】:

    标签: c# nhibernate linq-to-nhibernate queryover


    【解决方案1】:

    此声明(以上问题)

    queryOverPaciente = queryOverPaciente
        .Where(p => p.Identificacao.CompareTo(filtroRelatorio.MatriculaInicio) >= 0);
    

    将 C# 中定义的比较表示为string.CompareTo(VALUE)

    • 条件小于零 此实例在 VALUE 之前。
    • 零 此实例在排序顺序中的位置与 VALUE 相同。
    • 大于零 此实例遵循 VALUE。-或- VALUE 为空。

    所以这些有点相等:

    // negative means preceeds
    string.CompareTo(`**`VALUE`**`) >= 0
    // we only want follows or equals
    string >= VALUE
    

    而用SQL,我们可以直接表达:

    column >= @VALUE
    

    回到我们的 NH/C# 解决方案。我们可以这样定义

    queryOverPaciente
        .UnderlyingCriteria
         // GeProperty will generate >=
        .Add(Restrictions.GeProperty(
            // column
            Projections.Property(nameof(pacienteAlias.Identificacao)),
            // constant
            Projections.Constant(filtroRelatorio.MatriculaInicio)
        ));
    

    一个好奇心 - 要处理上面 C# 定义中所述的 NULL,我们可以例如添加ISNULL 语句(实际上更通用和更合适的COALESCE

    // use the Identificacao if filter is null
    var isNull = Projections.SqlFunction("Coalesce"
        , NHibernate.NHibernateUtil.String
        , Projections.Constant(filtroRelatorio.MatriculaInicio)
        , Projections.Property(nameof(pacienteAlias.Identificacao))
    );
    
    queryOverPaciente
        .UnderlyingCriteria
        .Add(Restrictions.GeProperty(
            Projections.Property(nameof(pacienteAlias.Identificacao)),
            // the ISNULL projection instead of constant
            isNull
        ));
    

    【讨论】:

      最近更新 更多