C# 为什么这个可选参数LINQ在哪里不起作用?

C# 为什么这个可选参数LINQ在哪里不起作用?,c#,asp.net,linq,controllers,C#,Asp.net,Linq,Controllers,当MesAno为“//string.Empty时 DateTime dateAux; int ano = 0; int mes = 0; if (MesAno.Trim() != "" && DateTime.TryParse("01/" + MesAno, out dateAux)) { ano = dateAux.Year; mes = dateAu

当MesAno为“//string.Empty时

        DateTime dateAux;
        int ano = 0;
        int mes = 0;
        if (MesAno.Trim() != "" && DateTime.TryParse("01/" + MesAno, out dateAux))
        {
            ano = dateAux.Year;
            mes = dateAux.Month;
        }


                lista = session.Query<Evidencias>().Timeout(30)
                    .Where(m => m.Produto.Distribuidora.Id == myUser.Terceiro.Distribuidora.Id)
                    //.Where(m => MesAno != "" ? (m.DataInclusao.Year == ano && m.DataInclusao.Month == mes) : true)
                    .Where(m => Produto != "" ? m.Produto.CodigoProduto.Contains(Produto) : true)
                    .Where(m => Titular != "" ? m.NomeTitular.Contains(Titular) : true)
                    .Where(m => Instalacao != "" ? m.CodigoInstalacao.Contains(Instalacao) : true)
                    .Where(m => ano != 0 ? m.DataInclusao.Year == ano : true)
                    .Where(m => mes != 0 ? m.DataInclusao.Month == mes : true)
                    .OrderByDescending(m => m.DataInclusao).Take(3000).ToList();
这一部分是:

datepart(year, evidencias0_.DataInclusao)=@P6 and datepart(month, evidencias0_.DataInclusao)=@P7
为什么不这样做:

@P6=1 and @P7=1

当然这很奇怪,但没有人是完美的——LINQ表达式树到SQL的转换是一个相当复杂的主题,需要考虑很多事情,因此可能会遗漏一些对人类来说“显而易见”的东西。因此,翻译并不总是完美的,但只要它不产生例外,并产生正确的结果,它应该是可以接受的

但是,您可以通过编写自定义条件
Where
扩展方法来帮助转换器避免冗余参数和条件(至少对于像您这样的顶级
IQueryable
),如下所示:

public static class QueryableExtensions
{
    public static IQueryable<T> WhereIf<T>(this IQueryable<T> source, bool condition, Expression<Func<T, bool>> predicate)
    {
        return condition ? source.Where(predicate) : source;
    }
}
公共静态类QueryableExtensions
{
公共静态IQueryable WhereIf(此IQueryable源、bool条件、表达式谓词)
{
返回条件?来源。其中(谓词):来源;
}
}
因此,您可以使用:

lista = session.Query<Evidencias>().Timeout(30)
      .Where(m => m.Produto.Distribuidora.Id == myUser.Terceiro.Distribuidora.Id)
      .WhereIf(Produto != "", m => m.Produto.CodigoProduto.Contains(Produto))
      .WhereIf(Titular != "", m => m.NomeTitular.Contains(Titular))
      .WhereIf(Instalacao != "", m => m.CodigoInstalacao.Contains(Instalacao))
      .WhereIf(ano != 0, m => m.DataInclusao.Year == ano)
      .WhereIf(mes != 0, m => m.DataInclusao.Month == mes)
      .OrderByDescending(m => m.DataInclusao).Take(3000).ToList();
lista=session.Query().超时(30)
.Where(m=>m.Produto.distribidora.Id==myUser.Terceiro.distribidora.Id)
.wheref(Produto!=”,m=>m.Produto.CodigoProduto.Contains(Produto))
.wheref(有名无实的!=”,m=>m.NomeTitular.Contains(有名无实的))
.wheref(Instalacao!=”,m=>m.codigo Instalacao.Contains(Instalacao))
.式中(ano!=0,m=>m.DataInclusao.Year==ano)
.式中(mes!=0,m=>m.DataInclusao.Month==mes)
.OrderByDescending(m=>m.DataInclusao).Take(3000).ToList();

生成的SQL不会有@P4、@P5、@P6、@P7参数和奇怪的条件

真棒的回答。简单、简单、快速、完美。把这门课放在我的项目中最好的方法是什么?一个包中的一个扩展类文件?或者一个LinqExtension类文件和这个一类和其他扩展Linq类???不客气,很高兴它有帮助:)关于这个问题,这是个人喜好/风格的问题。我通常有一个这样的类(文件)和许多我自己的扩展名,并将其包含(复制)到任何我需要的项目中。同样,这取决于您-使用适合您当前编码实践的任何东西:)
lista = session.Query<Evidencias>().Timeout(30)
      .Where(m => m.Produto.Distribuidora.Id == myUser.Terceiro.Distribuidora.Id)
      .WhereIf(Produto != "", m => m.Produto.CodigoProduto.Contains(Produto))
      .WhereIf(Titular != "", m => m.NomeTitular.Contains(Titular))
      .WhereIf(Instalacao != "", m => m.CodigoInstalacao.Contains(Instalacao))
      .WhereIf(ano != 0, m => m.DataInclusao.Year == ano)
      .WhereIf(mes != 0, m => m.DataInclusao.Month == mes)
      .OrderByDescending(m => m.DataInclusao).Take(3000).ToList();