是否使用EF核心值转换器阻止contains()linq方法转换为SQL?
我有一个电影
类。它具有类型
类型list< string>
的属性。我使用此精确 ef核心值转换将其存储在数据库中作为逗号分隔的字符串。
在我的方法中,我有电影
,它是类型iqueryable< Movie>
。该方法将类型作为list< string>
,我想根据流派过滤电影。
当我应用此过滤器时,此查询无法转换为数据库。
var genre = "Drama";
movies = movies.Where(m => m.Genres.Contains(genre));
如果我将.tolistasync()
应用于电影
,然后将所有电影拉到客户端,则该过滤器有效。但是我试图在数据库侧找到一种方法。
我还尝试了这些变体:
movies = movies.Where(m => m.Genres.Any(g => g.Contains(genre)));
movies = movies.Where(m => m.Genres.Any(g => g == genre));
我在以下错误消息中粘贴:
where(m => m.genres 。其他信息:方法“ system.linq.edumable.Contains”的翻译失败。如果可以将此方法映射到您的自定义函数,请参见 https://go.microsoft.com /fwlink/?linkID = 2132413 有关更多信息。可以通过可以翻译的形式重写查询,或者通过插入“可忽略的”,“ asasyncenumerable”,“ tolist”或“ tolistAsync”来明确切换到客户端评估。请参阅 https://go.microsoft.com/fwlink/?有关更多信息。
如果您想在计算机上重现:
- 克隆
- 在
searchmoviesextendedquery.cs
,第53行。 - 运行项目(
api
应该是启动项目),它将创建<<代码> freeflixDatabase SQL Server数据库和种子十部电影,然后将打开Swagger UI。 - 在Swagger UI中,运行
/api/catalog/moviessearch
带有消息主体的发布方法:{“ entres”:[“ string”]}
>
I have a Movie
class. It has a Genres
property of type List<string>
. I use this exact EF Core Value Conversion to store it in the database as a comma-separated string.
In my method, I have movies
, which is of type IQueryable<Movie>
. The method receives genres as a List<string>
, and I want to filter the movies according to the genres.
When I apply this filter, this query fails to translate to the database.
var genre = "Drama";
movies = movies.Where(m => m.Genres.Contains(genre));
The filter works if I apply .ToListAsync()
to movies
and pull all the movies to the client-side. But I'm trying to find a way to do this on the database-side.
I've also tried these variations:
movies = movies.Where(m => m.Genres.Any(g => g.Contains(genre)));
movies = movies.Where(m => m.Genres.Any(g => g == genre));
I'm pasting in the error message below:
.Where(m => m.Genres
.Contains(__genre_0))' could not be translated. Additional information: Translation of method 'System.Linq.Enumerable.Contains' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
If you want to reproduce it on your computer:
- Clone this github repository (filter-translation-issue branch)
- Put a breakpoint on
SearchMoviesExtendedQuery.cs
, line 53. - Run the project(
API
should be the startup project), it will create theFreeFlixDatabase
SQL Server database and seed ten movies, then it will open Swagger UI. - In the Swagger UI, run the
/api/catalog/MoviesSearch
POST method with the message body:{"genres":["string"]}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
方法1:如上所述,您可以以这种方式施放字符串:
Queryable.Where(x =&gt;((string)((string)(object)P.Convertible Property)) ==“ sup”)
方法2:
我看到现在无法直接在DB侧进行。但是,正如您提到的,可以在
tolistAsync()
之后在服务器端(称此客户端)上完成。另一种方法:不确定您的确切要求,但是您也可以考虑定时工作将数据从该表将其同步到另一个表格中,专门构造用于过滤。
Approach 1: As mentioned by John above, you can cast to a string an compare in that way:
queryable.Where(x => ((string)(object)p.ConvertibleProperty) == "sup")
Approach 2:
I see that this cannot be done directly on the db-side right now. But as you mention, it can be done on the server-side (you called this client side) after a
ToListAsync()
.Another approach: Not sure of your exact requirements, but you could also consider a timed job to sync the data from this table into another table specially structured for filtering.