首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >EF核心内插查询中整数列表的比较

EF核心内插查询中整数列表的比较
EN

Stack Overflow用户
提问于 2021-12-16 21:46:53
回答 3查看 238关注 0票数 0

我正在尝试将使用EF的.FromSqlRaw()方法运行的sql查询转换为使用.FromSqlInterpolated()运行的查询,这样它们就不会那么容易受到SQL注入攻击。我几乎把所有的东西都转换了,工作得很好,但唯一让我头疼的是如何在单个字段上通过一个或一个配置中的整数列表进行筛选。数据库是postgres,引号是因为我首先使用了代码EF Core,这意味着所有表都像类一样大写。ProjectTypeId是表中的整数列,projectTypes是List<int>类型变量。

我要替换的where子句中的代码是:

代码语言:javascript
运行
复制
WHERE ""PartGroups"".""ProjectTypeId"" IN({string.Join(",", projectTypes)})

我最近才能让它发挥作用的是:

代码语言:javascript
运行
复制
""PartGroups"".""ProjectTypeId""::text IN({string.Join(",", projectType)})

代码语言:javascript
运行
复制
""PartGroups"".""ProjectTypeId""::text LIKE ANY(ARRAY[{string.Join(",", projectTypes)}])

当projectTypes中只有一个值时,这些方法就会起作用,但是如果超过这个值,那么它就会失败。我不知道如何查看结果的查询+参数集,只是查询,所以我不知道它对参数做了什么,所以我一直在努力找出一些有用的东西。另外,查询总共有80个参数,因此手动设置每个参数的原始查询是不可行的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-12-16 23:38:11

一种可能的方法是利用EF的能力在原始的顶部作曲。

代码语言:javascript
运行
复制
context.SomeTable
  .FromSqlInterpolated($"SeLeCt t.* FrOm ...")
  .Where(st => idList.Contains(st.id))

EF将把您的SQL作为子查询,并在外部为您编写in。如果可以的话,DB查询优化器(很可能)会将IN推入子查询。

代码语言:javascript
运行
复制
SELECT ...
FROM 
  (
    SeLeCt t.* FrOm ...
  ) x
WHERE x.ID IN (.., ..)

如果您想查看所生成的SQL,并且您在EF5+上,那么最简单的方法就是做除ToList/ToArray之外的所有事情,并捕获查询:

代码语言:javascript
运行
复制
var q = context.Thing.Where(...)

然后在调试器中暂停并查看qq属性。您将得到完整的SQL文本,您可以将其插入SSMS并检查执行计划,检查它是否运行与单一级别(非分层)查询相同。

票数 1
EN

Stack Overflow用户

发布于 2021-12-17 07:36:02

您可以做的另一件事是自己在FormattableString中创建查询。只要FromSqlInterpolated收到一个FormattableString,它就会拆开它并参数化。

代码语言:javascript
运行
复制
    var args = new object[] { your, single, arguments, here}.Concat(yourListOfThingsHere.Cast<object>()).ToArray();

    var fs = FormattableStringFactory.Create(@"SELECT
  some,
  columns/{0},
  here 
FROM
  table t
WHERE  
  someColumn = {1} AND
  otherColumn BETWEEN {2} and {3} AND 
  columnToBeINned IN({" + string.Join("},{", Enumerable.Range(4, yourListOfThingsHere.Count)) + @"})
GROUP BY some, columns/{0}", args);

   var qq = context.Table.FromSqlInterpolated(fs).Where(m => ...);

当然,可以写个帮手来帮你.

票数 0
EN

Stack Overflow用户

发布于 2021-12-17 16:14:08

因此,我找到了一种方法,可以看到EF Core是如何解释内插查询的参数的,并且能够利用它来获得我想要的内容。因此,如果有人想要或需要坚持纯内插查询,您可以根据您的需要使用以下模式:

代码语言:javascript
运行
复制
WHERE MyTable.MyIntColumn::text LIKE ANY(Array[{string.Join(",", myIntList).Split(",", StringSplitOptions.None)}])

这也适用于文本值(只是不需要转换为文本),您可以使用如下通配符:

代码语言:javascript
运行
复制
WHERE MyTable.MyStringColumn ILIKE ANY(ARRAY[{("%" + string.Join("%,%", myStringList) + "%").Split(",", StringSplitOptions.None)}])
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70386005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档