【发布时间】:2020-03-03 20:42:33
【问题描述】:
我正在尝试在通用存储库(.NET Core 3.1 + EF Core 3.1)中实现动态过滤器
通过构建表达式树,但生成的 SQL 查询永远不会参数化(我正在通过 appsettings.json 中的"Microsoft.EntityFrameworkCore.Database.Command": "Information" 验证生成的查询,并在 Startup.cs 中有 EnableSensitiveDataLogging)
构建表达式树的代码如下(为简单起见,仅在此处使用字符串值):
public static IQueryable<T> WhereEquals<T>(IQueryable<T> query, string propertyName, object propertyValue)
{
var pe = Expression.Parameter(typeof(T));
var property = Expression.PropertyOrField(pe, propertyName);
var value = Expression.Constant(propertyValue);
var predicateBody = Expression.Equal(
property,
value
);
var whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new[] { typeof(T) },
query.Expression,
Expression.Lambda<Func<T, bool>>(predicateBody, new ParameterExpression[] { pe })
);
return query.Provider.CreateQuery<T>(whereCallExpression);
}
该方法有效,但值总是包含在生成的 SQL 查询中,我担心它会导致 SQL 注入。
这是一个生成的查询示例:
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand (33ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [p].[Id], [p].[Name], [p].[FirstName], [p].[Created], [p].[CreatedBy], [p].[Updated], [p].[UpdatedBy]
FROM [Persons] AS [p]
WHERE [p].[Name] = N'smith'
从 EF 团队成员 (@divega) 那里找到了可能的答案: Force Entity Framework to use SQL parameterization for better SQL proc cache reuse, 管理它使用 Where 方法,但生成的 SQL 仍然是一样的。
尝试使用 System.Linq.Dynamic.Core, 但它有同样的问题(生成的 SQL 查询没有参数化)。
有没有办法强制 Entity Framework Core 从表达式树生成参数化查询?
【问题讨论】:
-
你看过 LINQkit (albahari.com/nutshell/linqkit.aspx) 和 Predicate Builder (albahari.com/nutshell/predicatebuilder.aspx)。他们可能会为您提供另一条路径
-
感谢您提供的链接 - 有趣的阅读。由于我的过滤器是完全动态的和通用的,我没有找到一种方法来为仅在运行时知道的属性构建谓词,而不是直接使用表达式树。
标签: c# .net-core linq-to-sql entity-framework-core