【问题标题】:Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly.... by inserting a call to 'AsEnumerable要么以可以翻译的形式重写查询,要么显式切换到客户端评估....通过插入对“AsEnumerable”的调用
【发布时间】:2021-06-26 15:33:02
【问题描述】:

我正在开发一个 net 5 api,并尝试在查询数据库时实现 Iqueryable。我了解 IQueryable 和 IEnumerable 之间的根本区别。一切正常,直到我尝试实现搜索功能,然后我在 Postman 中收到上述消息:要么以可翻译的形式重写查询,要么通过插入对“AsEnumerable”、“AsAsyncEnumerable”的调用显式切换到客户端评估、“ToList”或“ToListAsync”。这是我的代码,感谢任何帮助,请随时指出我代码中的每个错误:

服务

 public async Task<IEnumerable<TransactionsForUserVM>> 
 ShowTransactionsForSpecificUser2(QueryParameters queryParameters,
     string email)
    {
        IQueryable<TransactionsForUserVM> transactions =
                          (from t in _context.StockTransactions
                           join u in _context.Users.Where(u => u.Email == email)                          
                           on t.Email equals u.Email 
                           join s in _context.Stocks
                           on t.StockId equals s.Id
                           select new TransactionsForUserVM 
                           {
                                Id = t.Id,
                                StockId = s.Id,
                                Stock = s.Symbol,
                                Quantity = t.Quantity,
                                Purchase = t.Purchase,
                                Price = t.Price,
                                Resolved = t.Resolved,
                                Date = t.Date,
                                Email = email
                                
                         }).AsQueryable().OrderBy(s => s.Date);         

        if (queryParameters.HasQuery())
        {
                transactions = transactions
                .Where(t => t.Stock.ToLowerInvariant().Contains(queryParameters.Query.ToLowerInvariant()));
        }                                    
           return await transactions.ToListAsync();    
    }

控制器:

[HttpGet]
public async Task<ActionResult<IEnumerable<TransactionsForUserVM>>> 
GetTransactionsForSpecificUser5(
    [FromQuery]QueryParameters queryParameters)
{
     var email = HttpContext.User.RetrieveEmailFromPrincipal();
     var list = await _transactionService.ShowTransactionsForSpecificUser2(queryParameters, 
     email);
    return Ok(list);
}

【问题讨论】:

  • 您引用的错误消息是实体框架错误消息。当您尝试使用 Entity Framework Linq 不支持的函数时会发生这种情况(与普通 Linq 不同的 Linq 风格)。
  • 可能是ToLowerInvariant无法翻译。但是通常数据库无论如何都会使用不区分大小写的匹配,所以只需将其删除
  • 谢谢伙计,就是这样,我花了很多时间在这上面,特别是因为一切都与 ienumerable 一起工作!

标签: c# api


【解决方案1】:

改变这个

.Where(t => t.Stock.ToLowerInvariant().Contains(queryParameters.Query.ToLowerInvariant()));

到这里:

.Where(t => t.Stock.Contains(queryParameters.Query));

EF Core 不知道如何将 ToLowerInvariant 转换为 SQL 命令,因此它会引发错误,因此您可以选择删除操作或执行客户端评估(将所有行拖出数据库,然后获取 c#做过滤器)。每当您看到“无法翻译”错误时,它都是“您使用了一些在 SQL 中不支持映射的 C# 事物”指示您需要重新设计 C# 的某些方面(使其不那么复杂)

您可以找到支持的操作列表(C# 是什么以及 efcore 可以将其翻译成什么)here。如果您不使用 SQLS,则有指向其他 DB 的链接 here 。例如,您可能需要访问第三方文档站点。你正在使用类似 postgres 的东西

【讨论】:

  • 谢谢,已经排除了 ToLowerInvariant 并且它工作正常,正如 Hans 指出的那样......我很乐意接受你作为正确答案,但这对 Hans 不公平......但再次感谢你的努力!
  • 那么汉斯不应该回答 cmets 中的问题(评论框的占位符文本甚至说不回答);他来这里的时间足够长,知道规则,我们都足够成熟,也足够有名气,早就不再关心积累假互联网积分了。我发布了一个答案(为您提供了其他信息),主要是为了让您可以将某些内容标记为已回答,因此问题在仪表板上显示为绿色,这意味着其他人知道它不再需要答案。通常,在 cmets 中回答的问题不会得到答案。家务也很头疼
  • (如果 Hans 确实发布了答案,请随意交换它;) - 您也可以在获得 cmets 指针后发布并接受自己的答案,这也有助于未来的访问者登陆同样的问题)
猜你喜欢
  • 2021-10-14
  • 1970-01-01
  • 2020-06-16
  • 2020-07-08
  • 2020-05-21
  • 1970-01-01
  • 2021-11-22
  • 1970-01-01
  • 2021-10-13
相关资源
最近更新 更多