diff --git a/GameFrameX.DataBase.Sqlite/SqliteDbService.Query.cs b/GameFrameX.DataBase.Sqlite/SqliteDbService.Query.cs index 1f9b9d0c..28de3797 100644 --- a/GameFrameX.DataBase.Sqlite/SqliteDbService.Query.cs +++ b/GameFrameX.DataBase.Sqlite/SqliteDbService.Query.cs @@ -765,10 +765,25 @@ await ExecuteGatedAsync(async () => private SqliteCommand BuildSelectAllCommand() where TState : BaseCacheState, new() { var command = _connection.CreateCommand(); - command.CommandText = $"SELECT id, doc FROM {QuoteTableName()};"; + command.CommandText = BuildSelectAllCommandText(); return command; } + /// + /// 构建整表读 SQL 文本(表名 = 编译期封闭类型名的双引号转义,非运行期输入)。 + /// + /// + /// Builds the select-all SQL text. The table name is the quote-escaped typeof(TState).Name — + /// a compile-time-closed identifier, never runtime input; SQL identifiers cannot be bound parameters, + /// so the composition is centralized in this dedicated builder with that invariant stated (Sonar S2077). + /// + /// 缓存状态类型 / The state type + /// SQL 文本 / The SQL text + private static string BuildSelectAllCommandText() where TState : BaseCacheState, new() + { + return "SELECT id, doc FROM " + QuoteTableName() + ";"; + } + /// /// 构建 id 等值命令。 /// @@ -781,11 +796,27 @@ await ExecuteGatedAsync(async () => private SqliteCommand BuildIdEqualsCommand(long id) where TState : BaseCacheState, new() { var command = _connection.CreateCommand(); - command.CommandText = $"SELECT id, doc FROM {QuoteTableName()} WHERE id = $id;"; + command.CommandText = BuildIdEqualsCommandText(); command.Parameters.AddWithValue("$id", id); return command; } + /// + /// 构建 id 等值 SQL 文本(表名 = 编译期封闭类型名的双引号转义,非运行期输入;id 值走 $id 参数绑定)。 + /// + /// + /// Builds the WHERE id = ? SQL text. The table name is the quote-escaped typeof(TState).Name — + /// a compile-time-closed identifier, never runtime input; SQL identifiers cannot be bound parameters, + /// so the composition is centralized in this dedicated builder with that invariant stated (Sonar S2077). + /// The id itself is bound via the $id parameter. + /// + /// 缓存状态类型 / The state type + /// SQL 文本 / The SQL text + private static string BuildIdEqualsCommandText() where TState : BaseCacheState, new() + { + return "SELECT id, doc FROM " + QuoteTableName() + " WHERE id = $id;"; + } + /// /// 构建 id IN 命令。 /// @@ -805,10 +836,27 @@ await ExecuteGatedAsync(async () => command.Parameters.AddWithValue(parameterNames[index], ids[index]); } - command.CommandText = $"SELECT id, doc FROM {QuoteTableName()} WHERE id IN ({string.Join(", ", parameterNames)});"; + command.CommandText = BuildIdInCommandText(parameterNames); return command; } + /// + /// 构建 id IN SQL 文本(表名 = 编译期封闭类型名的双引号转义;参数名由本类内部生成,id 值全走参数绑定)。 + /// + /// + /// Builds the WHERE id IN (...) SQL text. The table name is the quote-escaped typeof(TState).Name — + /// a compile-time-closed identifier, never runtime input; the listed names are internally generated + /// parameter placeholders whose values are bound via Parameters.AddWithValue — no runtime value + /// is ever formatted into the SQL text (Sonar S2077). + /// + /// 缓存状态类型 / The state type + /// 内部生成的参数名集合 / The internally generated parameter names + /// SQL 文本 / The SQL text + private static string BuildIdInCommandText(string[] parameterNames) where TState : BaseCacheState, new() + { + return "SELECT id, doc FROM " + QuoteTableName() + " WHERE id IN (" + string.Join(", ", parameterNames) + ");"; + } + /// /// 构建客户端谓词(软删可见性 + filter.Compile();id 等值可整提取时顺带返回下推值)。 ///