@@ -72,25 +72,29 @@ public void FlushUpdates()
7272 Emit ( new DBAdapterEvent { TablesUpdated = batchedUpdate } ) ;
7373 }
7474
75- private static void PrepareCommand ( SqliteCommand command , string query , object ? [ ] ? parameters )
75+ /// <summary>
76+ /// Replaces ? placeholders with named parameters and sets up the command.
77+ /// Returns the parameter names for reference.
78+ /// </summary>
79+ private static List < string > PrepareCommandParameters ( SqliteCommand command , string query , int parameterCount )
7680 {
77- if ( parameters == null || parameters . Length == 0 )
81+ var parameterNames = new List < string > ( ) ;
82+
83+ if ( parameterCount == 0 )
7884 {
7985 command . CommandText = query ;
80- return ;
86+ return parameterNames ;
8187 }
8288
83- var parameterNames = new List < string > ( ) ;
84-
8589 // Count placeholders
8690 int placeholderCount = query . Count ( c => c == '?' ) ;
87- if ( placeholderCount != parameters . Length )
91+ if ( placeholderCount != parameterCount )
8892 {
89- throw new ArgumentException ( "Number of provided parameters does not match the number of `?` placeholders in the query." ) ;
93+ throw new ArgumentException ( $ "Number of parameters ( { parameterCount } ) does not match the number of `?` placeholders ( { placeholderCount } ) in the query.") ;
9094 }
9195
9296 // Replace `?` sequentially with named parameters
93- for ( int i = 0 ; i < parameters . Length ; i ++ )
97+ for ( int i = 0 ; i < parameterCount ; i ++ )
9498 {
9599 string paramName = $ "@param{ i } ";
96100 parameterNames . Add ( paramName ) ;
@@ -102,17 +106,38 @@ private static void PrepareCommand(SqliteCommand command, string query, object?[
102106 }
103107
104108 query = string . Concat ( query . Substring ( 0 , index ) , paramName , query . Substring ( index + 1 ) ) ;
109+
105110 }
106111
107112 command . CommandText = query ;
108113
109- // Add parameters to the command
110- for ( int i = 0 ; i < parameters . Length ; i ++ )
114+ // Create empty parameter objects
115+ foreach ( var paramName in parameterNames )
111116 {
112- command . Parameters . AddWithValue ( parameterNames [ i ] , parameters [ i ] ?? DBNull . Value ) ;
117+ var parameter = command . CreateParameter ( ) ;
118+ parameter . ParameterName = paramName ;
119+ command . Parameters . Add ( parameter ) ;
113120 }
121+
122+ return parameterNames ;
114123 }
115124
125+ private static void PrepareCommand ( SqliteCommand command , string query , object ? [ ] ? parameters )
126+ {
127+ int paramCount = parameters ? . Length ?? 0 ;
128+ PrepareCommandParameters ( command , query , paramCount ) ;
129+
130+ // Set the values
131+ if ( parameters != null )
132+ {
133+ for ( int i = 0 ; i < parameters . Length ; i ++ )
134+ {
135+ command . Parameters [ i ] . Value = parameters [ i ] ?? DBNull . Value ;
136+ }
137+ }
138+ }
139+
140+
116141 public async Task < NonQueryResult > Execute ( string query , object ? [ ] ? parameters = null )
117142 {
118143 using var command = Db . CreateCommand ( ) ;
@@ -127,6 +152,44 @@ public async Task<NonQueryResult> Execute(string query, object?[]? parameters =
127152 } ;
128153 }
129154
155+ public async Task < NonQueryResult > ExecuteBatch ( string query , object ? [ ] [ ] ? parameters = null )
156+ {
157+ parameters ??= [ ] ;
158+
159+ if ( parameters . Length == 0 )
160+ {
161+ return new NonQueryResult { RowsAffected = 0 } ;
162+ }
163+
164+ int totalRowsAffected = 0 ;
165+
166+ var command = Db . CreateCommand ( ) ;
167+
168+ // Prepare command once with parameter placeholders
169+ int paramCount = parameters [ 0 ] ? . Length ?? 0 ;
170+ PrepareCommandParameters ( command , query , paramCount ) ;
171+
172+ // Execute for each parameter set (reuses compiled statement)
173+ foreach ( var paramSet in parameters )
174+ {
175+ if ( paramSet != null )
176+ {
177+ for ( int i = 0 ; i < paramSet . Length ; i ++ )
178+ {
179+ command . Parameters [ i ] . Value = paramSet [ i ] ?? DBNull . Value ;
180+ }
181+ }
182+
183+ totalRowsAffected += await command . ExecuteNonQueryAsync ( ) ;
184+ }
185+
186+ return new NonQueryResult
187+ {
188+ RowsAffected = totalRowsAffected ,
189+ InsertId = raw . sqlite3_last_insert_rowid ( Db . Handle )
190+ } ;
191+ }
192+
130193 public async Task < QueryResult > ExecuteQuery ( string query , object ? [ ] ? parameters = null )
131194 {
132195 var result = new QueryResult ( ) ;
0 commit comments