【发布时间】:2020-03-07 12:48:35
【问题描述】:
将我的 ASP.NET Core 2.2 应用程序迁移到 ASP.NET Core 3.0 后,我仍然遇到问题...
这一次,以前可以正常工作的 Linq-to-SQL 查询现在失败了,但以下形式除外:
The LINQ expression 'blahblah' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
太好了,所以我去https://go.microsoft.com/fwlink/?linkid=2101038。
我在那里读什么? 3.0 之前的版本用于接受无法在服务器上评估的查询,但现在大多不再是这种情况,而且:
如果 EF Core 在顶级投影以外的任何位置检测到无法转换到服务器的表达式,则会引发运行时异常。请参阅 how query works 以了解 EF Core 如何确定哪些内容无法翻译到服务器。
哦,还有一个链接。好的,我们跟着吧:
数据库提供程序确定可以在数据库中评估查询的哪些部分
!!!我应该能够在此链接下阅读它如何确定无法翻译到服务器的内容,以便我可以正确修改我的查询!!!
嗯,我所知道的是数据库提供者决定了这一点。这对我仍然没有帮助。
老实说,我认为这个特定的查询可以很好地转换为 SQL,因为它归结为(有点复杂)几个数字的比较(在这些数字之间有很多括号和 ||s 和 &&s括号)。
所以为了可读性和代码重用,查询使用了三个辅助方法,其中两个是模型类中定义的属性,将这些数字分组为两个元组和一个枚举...但是来吧,枚举转换为整数,元组知道它的长度,因此比较它们很容易减少到比较它们的元素等......
看来事情不是那么好,相反我必须做一些/全部:
- 删除辅助方法,将其代码复制粘贴到查询中。
- 手动解包元组。
- 手动将枚举转换为整数(啊,模型实例定义了一个枚举!)
我怎么知道以上哪些是必要的?
我如何知道我必须如何构建查询才能避免遇到此类问题?
查询必须满足哪些条件才能翻译成 db 语言?
【问题讨论】:
-
对于所有查询提供者来说,有一件事是肯定的——无法翻译自定义(帮助)方法。请记住,查询翻译器无法访问源代码,因此不知道自定义方法在里面做什么。未映射的(辅助)属性也是如此。
-
@IvanStoev 哎呀,这很难。复制粘贴有时复杂的条件是唯一的选择吗?似乎是可读性和可维护性的噩梦!
-
确实如此。但是它就是这样啊。该解决方案需要表达式组合,但 C# 编译器也无济于事。一些第 3 方库正在尝试解决它 - 例如 LinqKit、NeinLinq Lambda injection 和类似的。
-
@IvanStoev 也许像
private IQueryable<SomeType> AddCondition(IQueryable<SomeType> query) => query.Where(st => st.SomeMappedProp <= st.OtherMappedProp);??
标签: sql-server linq asp.net-core linq-to-sql entity-framework-core