Skip to content

Commit edc9f9b

Browse files
committed
Automatic configuration of temp tables and collection parameters for primitive types can be disabled.
1 parent 82bdabd commit edc9f9b

File tree

9 files changed

+164
-10
lines changed

9 files changed

+164
-10
lines changed

src/Thinktecture.EntityFrameworkCore.BulkOperations/EntityFrameworkCore/BulkOperations/BulkOperationConventionSetPlugin.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
22
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
3+
using Thinktecture.EntityFrameworkCore.Infrastructure;
34

45
namespace Thinktecture.EntityFrameworkCore.BulkOperations;
56

@@ -8,10 +9,21 @@ namespace Thinktecture.EntityFrameworkCore.BulkOperations;
89
/// </summary>
910
public class BulkOperationConventionSetPlugin : IConventionSetPlugin
1011
{
12+
private readonly IBulkOperationsDbContextOptionsExtensionOptions _options;
13+
14+
/// <summary>
15+
/// Initializes a new instance of <see cref="BulkOperationConventionSetPlugin"/>.
16+
/// </summary>
17+
public BulkOperationConventionSetPlugin(IBulkOperationsDbContextOptionsExtensionOptions options)
18+
{
19+
_options = options ?? throw new ArgumentNullException(nameof(options));
20+
}
21+
1122
/// <inheritdoc />
1223
public ConventionSet ModifyConventions(ConventionSet conventionSet)
1324
{
14-
conventionSet.ModelInitializedConventions.Add(TempTableConvention.Instance);
25+
if (_options.ConfigureTempTablesForPrimitiveTypes)
26+
conventionSet.ModelInitializedConventions.Add(TempTableConvention.Instance);
1527

1628
return conventionSet;
1729
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Microsoft.EntityFrameworkCore.Infrastructure;
2+
3+
namespace Thinktecture.EntityFrameworkCore.Infrastructure;
4+
5+
/// <summary>
6+
/// Options for bulk operations.
7+
/// </summary>
8+
public interface IBulkOperationsDbContextOptionsExtensionOptions : ISingletonOptions
9+
{
10+
/// <summary>
11+
/// Indication whether to configure temp tables for primitive types.
12+
/// </summary>
13+
bool ConfigureTempTablesForPrimitiveTypes { get; }
14+
}

src/Thinktecture.EntityFrameworkCore.SqlServer/EntityFrameworkCore/Infrastructure/SqlServerDbContextOptionsExtension.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,14 @@ public bool AddCustomQuerySqlGeneratorFactory
9595
/// </summary>
9696
public bool AddBulkOperationSupport { get; set; }
9797

98+
/// <summary>
99+
/// Indication whether to configure temp tables for primitive types.
100+
/// </summary>
101+
public bool ConfigureTempTablesForPrimitiveTypes { get; set; }
102+
98103
private JsonSerializerOptions? _collectionParameterJsonSerializerOptions;
99104
private bool _addCollectionParameterSupport;
105+
internal bool ConfigureCollectionParametersForPrimitiveTypes { get; private set; }
100106

101107
/// <summary>
102108
/// Changes the implementation of <see cref="IMigrationsSqlGenerator"/> to <see cref="ThinktectureSqlServerMigrationsSqlGenerator"/>.
@@ -116,6 +122,10 @@ public SqlServerDbContextOptionsExtension(RelationalDbContextOptionsExtension re
116122
[SuppressMessage("Usage", "EF1001", MessageId = "Internal EF Core API usage.")]
117123
public void ApplyServices(IServiceCollection services)
118124
{
125+
services.TryAddSingleton<SqlServerDbContextOptionsExtensionOptions>();
126+
services.AddSingleton<IBulkOperationsDbContextOptionsExtensionOptions>(provider => provider.GetRequiredService<SqlServerDbContextOptionsExtensionOptions>());
127+
services.AddSingleton<ISingletonOptions>(provider => provider.GetRequiredService<SqlServerDbContextOptionsExtensionOptions>());
128+
119129
if (AddCustomQueryableMethodTranslatingExpressionVisitorFactory)
120130
AddWithCheck<IQueryableMethodTranslatingExpressionVisitorFactory, ThinktectureSqlServerQueryableMethodTranslatingExpressionVisitorFactory, SqlServerQueryableMethodTranslatingExpressionVisitorFactory>(services);
121131

@@ -187,10 +197,14 @@ public void Register(Type serviceType, object implementationInstance)
187197
/// <summary>
188198
/// Enables and disables support for queryable parameters.
189199
/// </summary>
190-
public SqlServerDbContextOptionsExtension AddCollectionParameterSupport(bool addCollectionParameterSupport, JsonSerializerOptions? jsonSerializerOptions)
200+
public SqlServerDbContextOptionsExtension AddCollectionParameterSupport(
201+
bool addCollectionParameterSupport,
202+
JsonSerializerOptions? jsonSerializerOptions,
203+
bool configureCollectionParametersForPrimitiveTypes)
191204
{
192205
_addCollectionParameterSupport = addCollectionParameterSupport;
193206
_collectionParameterJsonSerializerOptions = jsonSerializerOptions;
207+
ConfigureCollectionParametersForPrimitiveTypes = addCollectionParameterSupport && configureCollectionParametersForPrimitiveTypes;
194208

195209
return this;
196210
}
@@ -244,7 +258,9 @@ public override int GetServiceProviderHashCode()
244258
hashCode.Add(_extension.AddCustomQuerySqlGeneratorFactory);
245259
hashCode.Add(_extension.AddCustomRelationalParameterBasedSqlProcessorFactory);
246260
hashCode.Add(_extension.AddBulkOperationSupport);
261+
hashCode.Add(_extension.ConfigureTempTablesForPrimitiveTypes);
247262
hashCode.Add(_extension._addCollectionParameterSupport);
263+
hashCode.Add(_extension.ConfigureCollectionParametersForPrimitiveTypes);
248264
hashCode.Add(_extension._collectionParameterJsonSerializerOptions);
249265
hashCode.Add(_extension.AddTenantDatabaseSupport);
250266
hashCode.Add(_extension.AddTableHintSupport);
@@ -261,7 +277,9 @@ public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo
261277
&& _extension.AddCustomQuerySqlGeneratorFactory == otherSqlServerInfo._extension.AddCustomQuerySqlGeneratorFactory
262278
&& _extension.AddCustomRelationalParameterBasedSqlProcessorFactory == otherSqlServerInfo._extension.AddCustomRelationalParameterBasedSqlProcessorFactory
263279
&& _extension.AddBulkOperationSupport == otherSqlServerInfo._extension.AddBulkOperationSupport
280+
&& _extension.ConfigureTempTablesForPrimitiveTypes == otherSqlServerInfo._extension.ConfigureTempTablesForPrimitiveTypes
264281
&& _extension._addCollectionParameterSupport == otherSqlServerInfo._extension._addCollectionParameterSupport
282+
&& _extension.ConfigureCollectionParametersForPrimitiveTypes == otherSqlServerInfo._extension.ConfigureCollectionParametersForPrimitiveTypes
265283
&& _extension._collectionParameterJsonSerializerOptions == otherSqlServerInfo._extension._collectionParameterJsonSerializerOptions
266284
&& _extension.AddTenantDatabaseSupport == otherSqlServerInfo._extension.AddTenantDatabaseSupport
267285
&& _extension.AddTableHintSupport == otherSqlServerInfo._extension.AddTableHintSupport
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using Microsoft.EntityFrameworkCore.Infrastructure;
2+
using Thinktecture.EntityFrameworkCore.Query.ExpressionTranslators;
3+
4+
namespace Thinktecture.EntityFrameworkCore.Infrastructure;
5+
6+
/// <summary>
7+
/// Options for the <see cref="RelationalMethodCallTranslatorPlugin"/>.
8+
/// </summary>
9+
public class SqlServerDbContextOptionsExtensionOptions : IBulkOperationsDbContextOptionsExtensionOptions
10+
{
11+
/// <inheritdoc />
12+
public bool ConfigureTempTablesForPrimitiveTypes { get; private set; }
13+
14+
/// <summary>
15+
/// Indication whether to configure collection parameters for primitive types.
16+
/// </summary>
17+
public bool ConfigureCollectionParametersForPrimitiveTypes { get; private set; }
18+
19+
/// <inheritdoc />
20+
public void Initialize(IDbContextOptions options)
21+
{
22+
var extension = GetExtension(options);
23+
24+
ConfigureTempTablesForPrimitiveTypes = extension.ConfigureTempTablesForPrimitiveTypes;
25+
ConfigureCollectionParametersForPrimitiveTypes = extension.ConfigureCollectionParametersForPrimitiveTypes;
26+
}
27+
28+
/// <inheritdoc />
29+
public void Validate(IDbContextOptions options)
30+
{
31+
var extension = GetExtension(options);
32+
33+
if (extension.ConfigureTempTablesForPrimitiveTypes != ConfigureTempTablesForPrimitiveTypes)
34+
throw new InvalidOperationException($"The setting '{nameof(SqlServerDbContextOptionsExtension.ConfigureTempTablesForPrimitiveTypes)}' has been changed.");
35+
36+
if (extension.ConfigureCollectionParametersForPrimitiveTypes != ConfigureCollectionParametersForPrimitiveTypes)
37+
throw new InvalidOperationException($"The setting '{nameof(SqlServerDbContextOptionsExtension.ConfigureCollectionParametersForPrimitiveTypes)}' has been changed.");
38+
}
39+
40+
private static SqlServerDbContextOptionsExtension GetExtension(IDbContextOptions options)
41+
{
42+
return options.FindExtension<SqlServerDbContextOptionsExtension>()
43+
?? throw new InvalidOperationException($"{nameof(SqlServerDbContextOptionsExtension)} not found in current '{nameof(IDbContextOptions)}'.");
44+
}
45+
}

src/Thinktecture.EntityFrameworkCore.SqlServer/EntityFrameworkCore/Parameters/SqlServerCollectionParameterConventionSetPlugin.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
22
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
3+
using Thinktecture.EntityFrameworkCore.Infrastructure;
34

45
namespace Thinktecture.EntityFrameworkCore.Parameters;
56

67
internal class SqlServerCollectionParameterConventionSetPlugin : IConventionSetPlugin
78
{
9+
private readonly SqlServerDbContextOptionsExtensionOptions _options;
10+
11+
public SqlServerCollectionParameterConventionSetPlugin(SqlServerDbContextOptionsExtensionOptions options)
12+
{
13+
_options = options ?? throw new ArgumentNullException(nameof(options));
14+
}
15+
816
public ConventionSet ModifyConventions(ConventionSet conventionSet)
917
{
10-
conventionSet.ModelInitializedConventions.Add(SqlServerCollectionParameterConvention.Instance);
18+
if (_options.ConfigureCollectionParametersForPrimitiveTypes)
19+
conventionSet.ModelInitializedConventions.Add(SqlServerCollectionParameterConvention.Instance);
1120

1221
return conventionSet;
1322
}

src/Thinktecture.EntityFrameworkCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,17 @@ public static class SqlServerDbContextOptionsBuilderExtensions
1919
/// </summary>
2020
/// <param name="sqlServerOptionsBuilder">SQL Server options builder.</param>
2121
/// <param name="addBulkOperationSupport">Indication whether to enable or disable the feature.</param>
22+
/// <param name="configureTempTablesForPrimitiveTypes">Indication whether to configure temp tables for primitive types.</param>
2223
/// <returns>Provided <paramref name="sqlServerOptionsBuilder"/>.</returns>
2324
public static SqlServerDbContextOptionsBuilder AddBulkOperationSupport(
2425
this SqlServerDbContextOptionsBuilder sqlServerOptionsBuilder,
25-
bool addBulkOperationSupport = true)
26+
bool addBulkOperationSupport = true,
27+
bool configureTempTablesForPrimitiveTypes = true)
2628
{
2729
return AddOrUpdateExtension(sqlServerOptionsBuilder, extension =>
2830
{
2931
extension.AddBulkOperationSupport = addBulkOperationSupport;
32+
extension.ConfigureTempTablesForPrimitiveTypes = addBulkOperationSupport && configureTempTablesForPrimitiveTypes;
3033
return extension;
3134
});
3235
}
@@ -37,13 +40,15 @@ public static SqlServerDbContextOptionsBuilder AddBulkOperationSupport(
3740
/// <param name="sqlServerOptionsBuilder">SQL Server options builder.</param>
3841
/// <param name="jsonSerializerOptions">JSON serialization options.</param>
3942
/// <param name="addCollectionParameterSupport">Indication whether to enable or disable the feature.</param>
43+
/// <param name="configureCollectionParametersForPrimitiveTypes">Indication whether to configure collection parameters for primitive types.</param>
4044
/// <returns>Provided <paramref name="sqlServerOptionsBuilder"/>.</returns>
4145
public static SqlServerDbContextOptionsBuilder AddCollectionParameterSupport(
4246
this SqlServerDbContextOptionsBuilder sqlServerOptionsBuilder,
4347
JsonSerializerOptions? jsonSerializerOptions = null,
44-
bool addCollectionParameterSupport = true)
48+
bool addCollectionParameterSupport = true,
49+
bool configureCollectionParametersForPrimitiveTypes = true)
4550
{
46-
return AddOrUpdateExtension(sqlServerOptionsBuilder, extension => extension.AddCollectionParameterSupport(addCollectionParameterSupport, jsonSerializerOptions));
51+
return AddOrUpdateExtension(sqlServerOptionsBuilder, extension => extension.AddCollectionParameterSupport(addCollectionParameterSupport, jsonSerializerOptions, configureCollectionParametersForPrimitiveTypes));
4752
}
4853

4954
/// <summary>

src/Thinktecture.EntityFrameworkCore.Sqlite/EntityFrameworkCore/Infrastructure/SqliteDbContextOptionsExtension.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ public bool AddCustomQuerySqlGeneratorFactory
7676
/// </summary>
7777
public bool AddBulkOperationSupport { get; set; }
7878

79+
/// <summary>
80+
/// Indication whether to configure temp tables for primitive types.
81+
/// </summary>
82+
public bool ConfigureTempTablesForPrimitiveTypes { get; set; }
83+
7984
/// <summary>
8085
/// Initializes new instance of <see cref="SqliteDbContextOptionsExtension"/>.
8186
/// </summary>
@@ -89,6 +94,10 @@ public SqliteDbContextOptionsExtension(RelationalDbContextOptionsExtension relat
8994
[SuppressMessage("Usage", "EF1001", MessageId = "Internal EF Core API usage.")]
9095
public void ApplyServices(IServiceCollection services)
9196
{
97+
services.TryAddSingleton<SqliteDbContextOptionsExtensionOptions>();
98+
services.AddSingleton<IBulkOperationsDbContextOptionsExtensionOptions>(provider => provider.GetRequiredService<SqliteDbContextOptionsExtensionOptions>());
99+
services.AddSingleton<ISingletonOptions>(provider => provider.GetRequiredService<SqliteDbContextOptionsExtensionOptions>());
100+
92101
if (AddCustomQueryableMethodTranslatingExpressionVisitorFactory)
93102
AddWithCheck<IQueryableMethodTranslatingExpressionVisitorFactory, ThinktectureSqliteQueryableMethodTranslatingExpressionVisitorFactory, SqliteQueryableMethodTranslatingExpressionVisitorFactory>(services);
94103

@@ -148,7 +157,8 @@ public override int GetServiceProviderHashCode()
148157
return HashCode.Combine(_extension.AddCustomQueryableMethodTranslatingExpressionVisitorFactory,
149158
_extension.AddCustomQuerySqlGeneratorFactory,
150159
_extension.AddCustomRelationalParameterBasedSqlProcessorFactory,
151-
_extension.AddBulkOperationSupport);
160+
_extension.AddBulkOperationSupport,
161+
_extension.ConfigureTempTablesForPrimitiveTypes);
152162
}
153163

154164
/// <inheritdoc />
@@ -158,7 +168,8 @@ public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo
158168
&& _extension.AddCustomQueryableMethodTranslatingExpressionVisitorFactory == otherSqliteInfo._extension.AddCustomQueryableMethodTranslatingExpressionVisitorFactory
159169
&& _extension.AddCustomQuerySqlGeneratorFactory == otherSqliteInfo._extension.AddCustomQuerySqlGeneratorFactory
160170
&& _extension.AddCustomRelationalParameterBasedSqlProcessorFactory == otherSqliteInfo._extension.AddCustomRelationalParameterBasedSqlProcessorFactory
161-
&& _extension.AddBulkOperationSupport == otherSqliteInfo._extension.AddBulkOperationSupport;
171+
&& _extension.AddBulkOperationSupport == otherSqliteInfo._extension.AddBulkOperationSupport
172+
&& _extension.ConfigureTempTablesForPrimitiveTypes == otherSqliteInfo._extension.ConfigureTempTablesForPrimitiveTypes;
162173
}
163174

164175
/// <inheritdoc />
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Microsoft.EntityFrameworkCore.Infrastructure;
2+
using Thinktecture.EntityFrameworkCore.Query.ExpressionTranslators;
3+
4+
namespace Thinktecture.EntityFrameworkCore.Infrastructure;
5+
6+
/// <summary>
7+
/// Options for the <see cref="RelationalMethodCallTranslatorPlugin"/>.
8+
/// </summary>
9+
public class SqliteDbContextOptionsExtensionOptions : IBulkOperationsDbContextOptionsExtensionOptions
10+
{
11+
/// <inheritdoc />
12+
public bool ConfigureTempTablesForPrimitiveTypes { get; private set; }
13+
14+
/// <inheritdoc />
15+
public void Initialize(IDbContextOptions options)
16+
{
17+
var extension = GetExtension(options);
18+
19+
ConfigureTempTablesForPrimitiveTypes = extension.ConfigureTempTablesForPrimitiveTypes;
20+
}
21+
22+
/// <inheritdoc />
23+
public void Validate(IDbContextOptions options)
24+
{
25+
var extension = GetExtension(options);
26+
27+
if (extension.ConfigureTempTablesForPrimitiveTypes != ConfigureTempTablesForPrimitiveTypes)
28+
throw new InvalidOperationException($"The setting '{nameof(SqliteDbContextOptionsExtension.ConfigureTempTablesForPrimitiveTypes)}' has been changed.");
29+
}
30+
31+
private static SqliteDbContextOptionsExtension GetExtension(IDbContextOptions options)
32+
{
33+
return options.FindExtension<SqliteDbContextOptionsExtension>()
34+
?? throw new InvalidOperationException($"{nameof(SqliteDbContextOptionsExtension)} not found in current '{nameof(IDbContextOptions)}'.");
35+
}
36+
}

src/Thinktecture.EntityFrameworkCore.Sqlite/Extensions/SqliteDbContextOptionsBuilderExtensions.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ public static class SqliteDbContextOptionsBuilderExtensions
1414
/// </summary>
1515
/// <param name="sqliteOptionsBuilder">SQLite options builder.</param>
1616
/// <param name="addBulkOperationSupport">Indication whether to enable or disable the feature.</param>
17+
/// <param name="configureTempTablesForPrimitiveTypes">Indication whether to configure temp tables for primitive types.</param>
1718
/// <returns>Provided <paramref name="sqliteOptionsBuilder"/>.</returns>
18-
public static SqliteDbContextOptionsBuilder AddBulkOperationSupport(this SqliteDbContextOptionsBuilder sqliteOptionsBuilder,
19-
bool addBulkOperationSupport = true)
19+
public static SqliteDbContextOptionsBuilder AddBulkOperationSupport(
20+
this SqliteDbContextOptionsBuilder sqliteOptionsBuilder,
21+
bool addBulkOperationSupport = true,
22+
bool configureTempTablesForPrimitiveTypes = true)
2023
{
2124
return AddOrUpdateExtension(sqliteOptionsBuilder, extension =>
2225
{
2326
extension.AddBulkOperationSupport = addBulkOperationSupport;
27+
extension.ConfigureTempTablesForPrimitiveTypes = addBulkOperationSupport && configureTempTablesForPrimitiveTypes;
2428
return extension;
2529
});
2630
}

0 commit comments

Comments
 (0)