在EF Core LINQ中使用Dictionary<string, string>:.Any无法被翻译

3

在EF Core的LINQ查询中使用.Any有什么技巧吗?

f.Filters的类型为Dictionary<string, string>

var items = await _dbContext.MyItems
                .Where(f => f.ID == 1)
                .Where(f => f.Filters.Keys.Any( k => k == "My Key"))
                .ToListAsync();

当我运行这个程序时,会得到以下结果:
LINQ表达式
DbSet<MyItems>()
 .Where(f => f.ID == 1)
 .Where(f => f.Filters.Keys
 .Any())

无法翻译。请将查询重写为可翻译的形式,或切换到客户端评估。

通过插入对AsEnumerable()、AsAsyncEnumerable()、ToList()或ToListAsync()之一的调用来显式转换。有关更多信息,请参见https://go.microsoft.com/fwlink/?linkid=2101038

我尝试按照文档添加了AsEnumerable,但似乎没有什么作用:

例如:

var items = await _dbContext.MyItems
                .Where(f => f.ID == 1)
                .Where(f => f.Filters.Keys.AsEnumerable().Any( k => k == "My Key"))
                .ToListAsync();

谢谢。是的,我最初尝试了ContainsKey,但是那给了我相同的问题。 - undefined
1
我会期望如此 =) 再次 - 更深入地研究 EF Core 内部是你支持这种查询的唯一选择。或者使用 FromSqlRaw,我认为这将是更简单的选项。 - undefined
2
提供信息,我认为你应该将 AsEnumerable 放在两个 Where 调用之间,而不是放在第二个调用内部。从听起来的声音来看,你需要一些类型的 Like 查询才能在 SQL 中完成,可能是 f => f.Filter.Contains("My Key") 或类似的东西。 - undefined
2
Where子句中不能使用转换后的属性。转换是在客户端进行的,EF不会将转换操作翻译成SQL语句。 - undefined
@GertArnold 这似乎是这个问题的答案。我正在使用一个转换后的属性,所以不能这样做是有道理的。 - undefined
显示剩余3条评论
1个回答

0
Where子句中不能使用转换属性。转换是在客户端进行的,EF不会将转换转化为SQL语句。 - @Gert Arnold在问题评论中提到
在调用.FirstOrDefaultAsync().ToDictionaryAsync().ToArrayAsync()等方法之后,您可以随时使用转换属性。这是因为调用.To或类似函数中的任何一个会执行数据库查询,将任何后续的LINQ操作从服务器端转移到客户端。
一个好的经验法则是,如果使用LINQ并且有以Async结尾的函数,那么这些调用及其非异步对应函数将执行数据库查询。

老问题了,我回答一下,这样其他有类似问题的人就不用在评论中翻找了。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接