11using System . Diagnostics . CodeAnalysis ;
22using System . Globalization ;
3+ using System . Text ;
4+ using System . Text . Json ;
35using Microsoft . EntityFrameworkCore . Infrastructure ;
6+ using Microsoft . EntityFrameworkCore . Metadata . Conventions . Infrastructure ;
47using Microsoft . EntityFrameworkCore . Migrations ;
58using Microsoft . EntityFrameworkCore . Query ;
69using Microsoft . EntityFrameworkCore . SqlServer . Query . Internal ;
10+ using Microsoft . EntityFrameworkCore . Storage ;
711using Microsoft . Extensions . DependencyInjection ;
812using Microsoft . Extensions . DependencyInjection . Extensions ;
13+ using Microsoft . Extensions . ObjectPool ;
914using Thinktecture . EntityFrameworkCore . BulkOperations ;
1015using Thinktecture . EntityFrameworkCore . Migrations ;
16+ using Thinktecture . EntityFrameworkCore . Parameters ;
1117using Thinktecture . EntityFrameworkCore . Query ;
1218using Thinktecture . EntityFrameworkCore . TempTables ;
1319
@@ -89,6 +95,9 @@ public bool AddCustomQuerySqlGeneratorFactory
8995 /// </summary>
9096 public bool AddBulkOperationSupport { get ; set ; }
9197
98+ private JsonSerializerOptions ? _collectionParameterJsonSerializerOptions ;
99+ private bool _addCollectionParameterSupport ;
100+
92101 /// <summary>
93102 /// Changes the implementation of <see cref="IMigrationsSqlGenerator"/> to <see cref="ThinktectureSqlServerMigrationsSqlGenerator"/>.
94103 /// </summary>
@@ -133,6 +142,16 @@ public void ApplyServices(IServiceCollection services)
133142 services . TryAddScoped < ITruncateTableExecutor > ( provider => provider . GetRequiredService < SqlServerBulkOperationExecutor > ( ) ) ;
134143 }
135144
145+ if ( _addCollectionParameterSupport )
146+ {
147+ var jsonSerializerOptions = _collectionParameterJsonSerializerOptions ?? new JsonSerializerOptions ( ) ;
148+
149+ services . AddSingleton < ICollectionParameterFactory > ( serviceProvider => new SqlServerCollectionParameterFactory ( jsonSerializerOptions ,
150+ serviceProvider . GetRequiredService < ObjectPool < StringBuilder > > ( ) ,
151+ serviceProvider . GetRequiredService < ISqlGenerationHelper > ( ) ) ) ;
152+ services . Add < IConventionSetPlugin , SqlServerCollectionParameterConventionSetPlugin > ( GetLifetime < IConventionSetPlugin > ( ) ) ;
153+ }
154+
136155 if ( UseThinktectureSqlServerMigrationsSqlGenerator )
137156 AddWithCheck < IMigrationsSqlGenerator , ThinktectureSqlServerMigrationsSqlGenerator , SqlServerMigrationsSqlGenerator > ( services ) ;
138157
@@ -163,6 +182,15 @@ public void Register(Type serviceType, object implementationInstance)
163182 _relationalOptions . Register ( serviceType , implementationInstance ) ;
164183 }
165184
185+ /// <summary>
186+ /// Enables and disables support for queryable parameters.
187+ /// </summary>
188+ public void AddCollectionParameterSupport ( bool addCollectionParameterSupport , JsonSerializerOptions ? jsonSerializerOptions )
189+ {
190+ _addCollectionParameterSupport = addCollectionParameterSupport ;
191+ _collectionParameterJsonSerializerOptions = jsonSerializerOptions ;
192+ }
193+
166194 /// <inheritdoc />
167195 public void Validate ( IDbContextOptions options )
168196 {
@@ -181,6 +209,7 @@ private class SqlServerDbContextOptionsExtensionInfo : DbContextOptionsExtension
181209 'Custom QuerySqlGeneratorFactory'={ _extension . AddCustomQuerySqlGeneratorFactory } ,
182210 'Custom RelationalParameterBasedSqlProcessorFactory'={ _extension . AddCustomRelationalParameterBasedSqlProcessorFactory } ,
183211 'BulkOperationSupport'={ _extension . AddBulkOperationSupport } ,
212+ 'CollectionParameterSupport'={ _extension . _addCollectionParameterSupport } ,
184213 'TenantDatabaseSupport'={ _extension . AddTenantDatabaseSupport } ,
185214 'TableHintSupport'={ _extension . AddTableHintSupport } ,
186215 'UseThinktectureSqlServerMigrationsSqlGenerator'={ _extension . UseThinktectureSqlServerMigrationsSqlGenerator }
@@ -196,13 +225,19 @@ public SqlServerDbContextOptionsExtensionInfo(SqlServerDbContextOptionsExtension
196225 /// <inheritdoc />
197226 public override int GetServiceProviderHashCode ( )
198227 {
199- return HashCode . Combine ( _extension . AddCustomQueryableMethodTranslatingExpressionVisitorFactory ,
200- _extension . AddCustomQuerySqlGeneratorFactory ,
201- _extension . AddCustomRelationalParameterBasedSqlProcessorFactory ,
202- _extension . AddBulkOperationSupport ,
203- _extension . AddTenantDatabaseSupport ,
204- _extension . AddTableHintSupport ,
205- _extension . UseThinktectureSqlServerMigrationsSqlGenerator ) ;
228+ var hashCode = new HashCode ( ) ;
229+
230+ hashCode . Add ( _extension . AddCustomQueryableMethodTranslatingExpressionVisitorFactory ) ;
231+ hashCode . Add ( _extension . AddCustomQuerySqlGeneratorFactory ) ;
232+ hashCode . Add ( _extension . AddCustomRelationalParameterBasedSqlProcessorFactory ) ;
233+ hashCode . Add ( _extension . AddBulkOperationSupport ) ;
234+ hashCode . Add ( _extension . _addCollectionParameterSupport ) ;
235+ hashCode . Add ( _extension . _collectionParameterJsonSerializerOptions ) ;
236+ hashCode . Add ( _extension . AddTenantDatabaseSupport ) ;
237+ hashCode . Add ( _extension . AddTableHintSupport ) ;
238+ hashCode . Add ( _extension . UseThinktectureSqlServerMigrationsSqlGenerator ) ;
239+
240+ return hashCode . ToHashCode ( ) ;
206241 }
207242
208243 /// <inheritdoc />
@@ -213,6 +248,8 @@ public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo
213248 && _extension . AddCustomQuerySqlGeneratorFactory == otherSqlServerInfo . _extension . AddCustomQuerySqlGeneratorFactory
214249 && _extension . AddCustomRelationalParameterBasedSqlProcessorFactory == otherSqlServerInfo . _extension . AddCustomRelationalParameterBasedSqlProcessorFactory
215250 && _extension . AddBulkOperationSupport == otherSqlServerInfo . _extension . AddBulkOperationSupport
251+ && _extension . _addCollectionParameterSupport == otherSqlServerInfo . _extension . _addCollectionParameterSupport
252+ && _extension . _collectionParameterJsonSerializerOptions == otherSqlServerInfo . _extension . _collectionParameterJsonSerializerOptions
216253 && _extension . AddTenantDatabaseSupport == otherSqlServerInfo . _extension . AddTenantDatabaseSupport
217254 && _extension . AddTableHintSupport == otherSqlServerInfo . _extension . AddTableHintSupport
218255 && _extension . UseThinktectureSqlServerMigrationsSqlGenerator == otherSqlServerInfo . _extension . UseThinktectureSqlServerMigrationsSqlGenerator ;
@@ -225,6 +262,7 @@ public override void PopulateDebugInfo(IDictionary<string, string> debugInfo)
225262 debugInfo [ "Thinktecture:CustomQuerySqlGeneratorFactory" ] = _extension . AddCustomQuerySqlGeneratorFactory . ToString ( CultureInfo . InvariantCulture ) ;
226263 debugInfo [ "Thinktecture:CustomRelationalParameterBasedSqlProcessorFactory" ] = _extension . AddCustomRelationalParameterBasedSqlProcessorFactory . ToString ( CultureInfo . InvariantCulture ) ;
227264 debugInfo [ "Thinktecture:BulkOperationSupport" ] = _extension . AddBulkOperationSupport . ToString ( CultureInfo . InvariantCulture ) ;
265+ debugInfo [ "Thinktecture:CollectionParameterSupport" ] = _extension . _addCollectionParameterSupport . ToString ( CultureInfo . InvariantCulture ) ;
228266 debugInfo [ "Thinktecture:TenantDatabaseSupport" ] = _extension . AddTenantDatabaseSupport . ToString ( CultureInfo . InvariantCulture ) ;
229267 debugInfo [ "Thinktecture:TableHintSupport" ] = _extension . AddTableHintSupport . ToString ( CultureInfo . InvariantCulture ) ;
230268 debugInfo [ "Thinktecture:UseThinktectureSqlServerMigrationsSqlGenerator" ] = _extension . UseThinktectureSqlServerMigrationsSqlGenerator . ToString ( CultureInfo . InvariantCulture ) ;
0 commit comments