【发布时间】:2018-08-25 12:11:45
【问题描述】:
我们有一列将 JSON 数据存储为字符串。此 JSON 数据通过物化读取并转换为 IDictionary<string, object>。这一切都很好,直到我想过滤它。仅在从数据库中获取数据后才应用过滤。我们将拥有数百万条记录,因此这是不可接受的。显然,我的过滤器作为 WHERE 子句被 EF Core 完全忽略了,因为它可能不知道如何解析 MethodCallExpressions。
我正在寻找一种方法,通过我拥有的表达式树,尽可能接近下面的 SQL 查询。
我需要转换这个:
.Call System.Linq.Queryable.Where(
.Constant<QueryTranslator`1[Setting]>(QueryTranslator`1[Setting]),
'(.Lambda #Lambda1<System.Func`2[Setting,System.Boolean]>))
.Lambda #Lambda1<System.Func`2[Setting,System.Boolean]>(Setting $$it)
{
((System.Nullable`1[System.Int32]).If (
$$it.Value != null && .Call ($$it.Value).ContainsKey("Name")
) {
($$it.Value).Item["Name"]
} .Else {
null
} > (System.Nullable`1[System.Int32]).Constant<Microsoft.AspNet.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.Int32]>(Microsoft.AspNet.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.Int32]).TypedProperty)
== .Constant<System.Nullable`1[System.Boolean]>(True)
}
进入这个:
SELECT *
FROM [Setting]
WHERE JSON_VALUE([Value], 'lax $.Name') > 1; -- [Value_Name] > 1 is also fine
有了ExpressionVisitor,我成功地接近了
WHERE [Value] = 'Something' 但这仅适用于字符串并且缺少键名。
【问题讨论】:
-
在这种情况下,向下钻取到 raw sql 会更容易,而不是尝试将工具弯曲到您的意愿以获取不支持开箱即用的东西......
-
EF Core 积压中有一个功能:github.com/aspnet/EntityFrameworkCore/issues/4021