是否使用EF核心值转换器阻止contains()linq方法转换为SQL?

发布于 2025-01-25 03:39:38 字数 1849 浏览 4 评论 0原文

我有一个电影类。它具有类型类型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 the FreeFlixDatabase 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情栀口红 2025-02-01 03:39:38

方法1:如上所述,您可以以这种方式施放字符串:

Queryable.Where(x =&gt;((string)((string)(object)P.Convertible Property)) ==“ sup”)

方法2:
我看到现在无法直接在DB侧进行。但是,正如您提到的,可以在tolistAsync()之后在服务器端(称此客户端)上完成。

        var r = _context.TblExample.Where(w => w.Filter == filter);
        if (await r.AnyAsync())
        {
            var rs = await r.ToListAsync();
            var w = rs.Where(w => w.Categories.Contains(category));
            return w.ToList();
        }

另一种方法:不确定您的确切要求,但是您也可以考虑定时工作将数据从该表将其同步到另一个表格中,专门构造用于过滤。

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().

        var r = _context.TblExample.Where(w => w.Filter == filter);
        if (await r.AnyAsync())
        {
            var rs = await r.ToListAsync();
            var w = rs.Where(w => w.Categories.Contains(category));
            return w.ToList();
        }

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文