[英]How to compare a list of integers in EF Core Interpolated Query
我正在嘗試將使用 EF Core 的.FromSqlRaw() 方法運行的 sql 查詢轉換為使用.FromSqlInterpolated() 運行的查詢,因此它們不太容易受到 SQL 注入攻擊。 我幾乎把所有東西都轉換了並且工作正常,但讓我難過的一件事是如何通過單個字段的或配置中的整數列表進行過濾。 數據庫是 postgres,引號是因為我首先使用代碼 EF Core,這意味着所有表都像 class 一樣大寫。 ProjectTypeId 是我表中的 integer 列,projectTypes 是List<int>
類型變量。
我要替換的 where 子句中的代碼是:
WHERE ""PartGroups"".""ProjectTypeId"" IN({string.Join(",", projectTypes)})
我能夠讓它工作的最接近的是:
""PartGroups"".""ProjectTypeId""::text IN({string.Join(",", projectType)})
或者
""PartGroups"".""ProjectTypeId""::text LIKE ANY(ARRAY[{string.Join(",", projectTypes)}])
當 projectTypes 中只有一個值時,這些將起作用,但不止於此,它會失敗。 我不知道如何查看生成的查詢+參數集,只是查詢,所以我不確定它對參數做了什么,所以我一直在努力找出可行的方法。 此外,該查詢總共有大約 80 個參數,因此使用原始查詢手動設置每個參數是不可行的。
也許,您可以使用它的一種方法是利用 EF 在原始文件的頂部進行組合的能力
context.SomeTable
.From..($"SELECT t.* FROM ...")
.Where(st => idList.Contains(st.id))
EF 會將您的 SQL 作為子查詢放入,並在外部為您寫入 IN。 如果可以的話,數據庫查詢優化器將(可能)然后將 IN 推送到子查詢中。
您可以做的另一件事是自己在 FormattableString 中創建查詢。 只要 FromSqlInterpolated 收到一個 FormattableString ,它就會把它拆開並參數化
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 => ...);
當然,可以編寫一個助手來為您執行此操作...
因此,我找到了一種方法來實際查看 EF Core 如何解釋插值查詢的參數,並且能夠使用它來獲得我想要的結果。 因此,以防萬一有人想要或需要堅持純插值查詢,您可以根據需要使用以下模式:
WHERE MyTable.MyIntColumn::text LIKE ANY(Array[{string.Join(",", myIntList).Split(",", StringSplitOptions.None)}])
這也適用於文本值(只是不需要轉換為文本),您可以使用如下通配符:
WHERE MyTable.MyStringColumn ILIKE ANY(ARRAY[{("%" + string.Join("%,%", myStringList) + "%").Split(",", StringSplitOptions.None)}])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.