【问题标题】:An exception was thrown while attempting to evaluate a LINQ query parameter expression尝试评估 LINQ 查询参数表达式时引发异常
【发布时间】:2021-04-25 01:30:17
【问题描述】:

标题有误。可能我必须控制 string.IsNullOrEmpty(searchString) 但我没有。我的代码如下。请帮帮我
谢谢大家我解决了这个问题。问题不在这里。我的路线代码有问题。因为搜索不同,我会写我的路线代码

endpoints.MapControllerRoute(
                name:"search",
                pattern: "{search}",
                defaults: new {controller="Shop",action="search"}
               );

但不是来自模式:“{search} 应该是这种模式:“搜索” 感谢所有帮助过的人

   public List<Product> GetSearchResult(string searchString)
        {
              using (var context = new ShopContext())
            {
                var products = context 
                .Products
                .Where(i=>  i.IsApproved && (i.Name.ToLower().Contains(searchString.ToLower()) ||  i.Description.ToLower().Contains(searchString.ToLower()))) 
                .AsQueryable();
                
                return products.ToList();
            }
        }

【问题讨论】:

  • 请添加抛出的异常。
  • 内部异常。
  • 这可能是尝试在单个语句中做太多事情的情况。除非您可以将其分解为多个进程,否则很难知道您的错误在哪里。如果您可以粘贴 FULL 错误以及堆栈跟踪,那将有所帮助。
  • 最可能的原因是searchString 为空。您需要先检查它是否为空。或者像这样searchString = searchString ?? ""; 简单地在开头标准化它的值
  • 你已经破坏了一切,所有的痕迹使以下所有答案都变得毫无意义=))好人。下次,请保持您的问题不变。这不是您可以用您自己解决的答案替换几乎所有内容的地方。您可以像其他人一样在单独的 Answer 中发布自己的答案。 Q&A 的目的不仅仅是帮助解决您自己的问题,主要目的是帮助解决其他开发者也遇到的类似问题。这意味着所有的问题和答案可能会帮助很多人,而不仅仅是这次。

标签: c# .net asp.net-mvc asp.net-core asp.net-web-api


【解决方案1】:

我将把它分解如下:

public List<Product> GetSearchResult(string searchString)
{
   // What do you want to do if searchString is null or blank? (Pick one:)

   // You could send back an empty result...
   if (String.IsNullOrWhiteSpace(searchString))
      return null;

   // Or you could convert it to a blank string
   if (searchString == null)
       searchString = "";

   List<Product> products = new List<Product>();

    using (var context = new ShopContext())
    {
        products = context.Products.ToList();
    }

    // Always check for null and empty after going to the DB
    if (products == null || products.count = 0)
        return null;

   // If we are still here, then we can finally do the search
   List<Product> results = products.Where(i=> i.IsApproved && 
        (i.Name != null && i.Name.ToLower().Contains(searchString.ToLower()) ||
        (i.Description != null && i.Description.ToLower().Contains(searchString.ToLower())));

   return results;
}

注意:我没有对此进行测试,在最后一个带有 ('s 和 )'s 的 LINQ 语句中可能存在语法错误。

编辑:

上面的示例将拉回Product 表中的所有记录,然后过滤内存中的结果。如果您想避免这种情况,那么我认为这应该可行:

public List<Product> GetSearchResult(string searchString)
{
   // What do you want to do if searchString is null or blank? (Pick one:)

   // You could send back an empty result...
   if (String.IsNullOrWhiteSpace(searchString))
      return null;

   // Or you could convert it to a blank string
   if (searchString == null)
       searchString = "";

    using (var context = new ShopContext())
    {
        List<Product> products = context.Products.Where(i=> i.IsApproved && 
        (i.Name != null && i.Name.ToLower().Contains(searchString.ToLower()) ||
        (i.Description != null && i.Description.ToLower().Contains(searchString.ToLower()))).ToList();

       return products;
    }
}

这与您的 OP 之间的主要区别在于,我们正在检查 NameDescription 上的空值——我相信这样做的方式是 EF 可以将查询。

【讨论】:

  • 好吧,我对 EF 了解不多。但i.Namei.Description 仍可能是null 并在尝试对其调用ToLower 时抛出异常,这将导致LINQ 失败。
  • @MichaelChen,好点子!我会修复的。在我的回答中。当搜索完成时,我们已经在 EF 之外,我们只是在使用内存中的列表。数据库之旅发生在products = context.Products.ToList(),它被翻译成一个查询。在这种情况下,查询是“SELECT * FROM Products”。
  • 只是要注意加载所有记录然后在内存中过滤会破坏表达式树的好处。特别是如果有很多产品。
  • @WiktorZychla,是的,因此是我的编辑。 (刷新页面?)
  • 啊,明白了 :-)
【解决方案2】:

手头的信息不多,但我认为 LINQ 失败是因为字符串为空。 另外,您为什么要创建一个可查询的结果然后生成一个列表?

public List<Product> GetSearchResult(string searchString) {
    static bool Contains(string a, string b) {
        return a.ToLower().Contains(b.ToLower());
    }

    using (var context = new ShopContext()) {
        return context
        .Products
        .Where(i => i.IsApproved)
        .Where(i => i.Name is null ? false : Contains(i.Name, searchString)
        || i.Description is null ? false : Contains(i.Description, searchString))
        .ToList();
    }
}

【讨论】:

  • 这个内部函数会抛出,因为它没有翻译成 sql。
  • @WiktorZychla 我不明白你的意思。这段代码和 SQL 有什么关系?
  • Shop 上下文看起来像将表达式树转换为查询的 EF 上下文。
  • 维克托是对的。 context是数据库的企业框架表示,任何LINQ查询都需要翻译成SQL
  • 谢谢大家我解决了这个问题。问题不在这里。我的路线代码有问题。我更改并在上面添加了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-07
  • 1970-01-01
  • 2017-04-20
  • 1970-01-01
  • 2023-01-03
相关资源
最近更新 更多