[英]EF Core/Npgsql Parameterize an entire where clause
我正在嘗試將 Entity Framework Core 與 Npgsql 一起使用來執行原始 SQL 查詢,其中 WHERE 子句部分是從數據庫中提取的,實際“值”由用戶提供。 作為一個具體的例子:
這部分 SQL 是 static
SELECT TITLE as TitleField,
GEOM as GeomField,
GEOM_X as XField,
GEOM_Y as YField
FROM fdw_public."MY_TABLE"
然后管理員可以在數據庫中設置 WHERE 子句,例如:
COLUMNNAME LIKE '%{search}%'
或者
OTHER_COLUMNNAME = '{search}' AND COLUMNNAME = 'Something Static';
這在編譯時是未知的,可能是任何有效的 WHERE 子句。
{search} 部分是一個占位符。 我相信來自數據庫的子句,這僅由應用程序所有者控制,如果他們想破壞自己的表,那很好。
最終結果是這個 SQL
SELECT TITLE as TitleField,
GEOM as GeomField,
GEOM_X as XField,
GEOM_Y as YField
FROM fdw_public."MY_TABLE"
WHERE COLUMNNAME LIKE '%{search}%'
然而,{search} 部分是用戶輸入(來自 web 應用程序),因此需要參數化。
以下工作,但顯然對 SQL 注入非常開放
var sql = $@"SELECT TITLE as TitleField,
GEOM as GeomField,
XFIELD as XField,
YFIELD as YField
FROM fdw_public."MY_TABLE"
WHERE {searchDefinition.WhereClause.Replace("{search}", searchTerm)}";
var dbResults = _context.DatabaseSearchResults.FromSqlRaw(sql).ToList();
所以我嘗試為整個 where 子句使用一個參數
var sql = $@"SELECT TITLE as TitleField,
GEOM as GeomField,
XFIELD as XField,
YFIELD as YField
FROM fdw_public."MY_TABLE"
WHERE @whereClause";
var whereClauseParam = new Npgsql.NpgsqlParameter("@whereClause", searchDefinition.WhereClause.Replace("{search}", searchTerm));
var dbResults = _context.DatabaseSearchResults.FromSqlRaw(sql,whereClauseParam).ToList();
但這會從 Npgsql 引發以下異常
42804:WHERE 的參數必須是類型 boolean,而不是類型文本
這對我來說確實很有意義,因為對整個子句進行參數化感覺是錯誤的,但我想不出更好的方法來解決它。
理想情況下,我只需要對搜索詞進行參數化,就像這樣
var sql = $@"SELECT TITLE as TitleField,
GEOM as GeomField,
XFIELD as XField,
YFIELD as YField
FROM fdw_public."MY_TABLE"
WHERE {searchDefinition.WhereClause.Replace("{search}","@p0")}";
var searchTermParam = new Npgsql.NpgsqlParameter("p0", searchTerm);
var dbResults = _context.DatabaseSearchResults.FromSqlRaw(sql, searchTermParam).ToList();
但同樣,這是行不通的,這是可以理解的,因為它是按字面解釋的。
我覺得這可能會改變我完全這樣做的方式,或者更糟糕的是,使用一些眾所周知的清理來清理搜索字符串,但我不想這樣做,我想使用參數。
無論哪種方式,總而言之,要求是這樣的
嘗試將"{search}"
替換為"{0}"
並將searchTerm
作為parameters
傳遞給FromSqlRaw
:
var sql = $@"SELECT TITLE as TitleField,
GEOM as GeomField,
XFIELD as XField,
YFIELD as YField
FROM fdw_public.""MY_TABLE""
WHERE {searchDefinition.WhereClause.Replace("{search}","{0}")}";
var dbResults = _context.DatabaseSearchResults.FromSqlRaw(sql, searchTerm).ToList();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.