From e94c1cbc890eba2c22e0030cd74d87afb7708908 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Tue, 12 Jan 2021 22:47:09 +0100 Subject: [PATCH 1/2] Fixup for #23376 --- .../Query/Internal/SqlExpressionFactory.cs | 1 - .../RelationalForeignKeyExtensions.cs | 21 +++++++++++-------- .../CosmosApiConsistencyTest.cs | 7 ------- .../DesignApiConsistencyTest.cs | 7 ------- .../InMemoryApiConsistencyTest.cs | 7 ------- .../ProxiesApiConsistencyTest.cs | 7 ------- .../RelationalApiConsistencyTest.cs | 6 ------ .../ApiConsistencyTestBase.cs | 10 ++++++--- .../SqlServerApiConsistencyTest.cs | 7 ------- .../SqlServerNTSApiConsistencyTest.cs | 7 ------- .../SqliteApiConsistencyTest.cs | 7 ------- .../SqliteNTSApiConsistencyTest.cs | 7 ------- test/EFCore.Tests/ApiConsistencyTest.cs | 6 ------ 13 files changed, 19 insertions(+), 81 deletions(-) diff --git a/src/EFCore.Cosmos/Query/Internal/SqlExpressionFactory.cs b/src/EFCore.Cosmos/Query/Internal/SqlExpressionFactory.cs index 2070f1b9fbc..ebc047a9239 100644 --- a/src/EFCore.Cosmos/Query/Internal/SqlExpressionFactory.cs +++ b/src/EFCore.Cosmos/Query/Internal/SqlExpressionFactory.cs @@ -142,7 +142,6 @@ when sqlUnaryExpression.IsLogicalNot(): throw new InvalidOperationException( CosmosStrings.UnsupportedOperatorForSqlExpression( sqlUnaryExpression.OperatorType, typeof(SqlUnaryExpression).ShortDisplayName())); - ; } return new SqlUnaryExpression(sqlUnaryExpression.OperatorType, operand, resultType, resultTypeMapping); diff --git a/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs b/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs index 1f8062934f2..e784f74e10f 100644 --- a/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs +++ b/src/EFCore.Relational/Metadata/Internal/RelationalForeignKeyExtensions.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; @@ -44,9 +45,7 @@ public static bool AreCompatible( var columnNames = foreignKey.Properties.GetColumnNames(storeObject); var duplicateColumnNames = duplicateForeignKey.Properties.GetColumnNames(storeObject); if (columnNames is null - || duplicateColumnNames is null - || principalTable is null - || duplicatePrincipalTable is null) + || duplicateColumnNames is null) { if (shouldThrow) { @@ -66,11 +65,13 @@ public static bool AreCompatible( return false; } - var principalColumns = foreignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value); - var duplicatePrincipalColumns = duplicateForeignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value); - if (principalTable != duplicatePrincipalTable - || principalColumns == null - || duplicatePrincipalColumns == null) + if (principalTable is null + || duplicatePrincipalTable is null + || principalTable != duplicatePrincipalTable + || !(foreignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value) + is IReadOnlyList principalColumns) + || !(duplicateForeignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value) + is IReadOnlyList duplicatePrincipalColumns)) { if (shouldThrow) { @@ -81,7 +82,9 @@ public static bool AreCompatible( duplicateForeignKey.Properties.Format(), duplicateForeignKey.DeclaringEntityType.DisplayName(), foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(), - foreignKey.GetConstraintName(storeObject, principalTable.Value), + principalTable.HasValue + ? foreignKey.GetConstraintName(storeObject, principalTable.Value) + : foreignKey.GetDefaultName(), principalType.GetSchemaQualifiedTableName(), duplicatePrincipalType.GetSchemaQualifiedTableName())); } diff --git a/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs b/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs index 813e6200685..b66fd4fed42 100644 --- a/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/CosmosApiConsistencyTest.cs @@ -27,13 +27,6 @@ protected override Assembly TargetAssembly public class CosmosApiConsistencyFixture : ApiConsistencyFixtureBase { - public override bool TryGetProviderOptionsDelegate(out Action configureOptions) - { - configureOptions = b => CosmosTestHelpers.Instance.UseProviderOptions(b); - - return true; - } - public override HashSet FluentApiTypes { get; } = new HashSet { typeof(CosmosModelBuilderExtensions), diff --git a/test/EFCore.Design.Tests/DesignApiConsistencyTest.cs b/test/EFCore.Design.Tests/DesignApiConsistencyTest.cs index e66b1cf6086..6b0a22c1cc4 100644 --- a/test/EFCore.Design.Tests/DesignApiConsistencyTest.cs +++ b/test/EFCore.Design.Tests/DesignApiConsistencyTest.cs @@ -26,13 +26,6 @@ protected override Assembly TargetAssembly public class DesignApiConsistencyFixture : ApiConsistencyFixtureBase { - public override bool TryGetProviderOptionsDelegate(out Action configureOptions) - { - configureOptions = b => InMemoryTestHelpers.Instance.UseProviderOptions(b); - - return true; - } - public override HashSet FluentApiTypes { get; } = new HashSet { typeof(DesignTimeServiceCollectionExtensions) }; } } diff --git a/test/EFCore.InMemory.FunctionalTests/InMemoryApiConsistencyTest.cs b/test/EFCore.InMemory.FunctionalTests/InMemoryApiConsistencyTest.cs index a9553d31d1d..a74d4e6475d 100644 --- a/test/EFCore.InMemory.FunctionalTests/InMemoryApiConsistencyTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/InMemoryApiConsistencyTest.cs @@ -26,13 +26,6 @@ protected override Assembly TargetAssembly public class InMemoryApiConsistencyFixture : ApiConsistencyFixtureBase { - public override bool TryGetProviderOptionsDelegate(out Action configureOptions) - { - configureOptions = b => InMemoryTestHelpers.Instance.UseProviderOptions(b); - - return true; - } - public override HashSet FluentApiTypes { get; } = new HashSet { typeof(InMemoryServiceCollectionExtensions), diff --git a/test/EFCore.Proxies.Tests/ProxiesApiConsistencyTest.cs b/test/EFCore.Proxies.Tests/ProxiesApiConsistencyTest.cs index 546d7924cb7..f5c40462f60 100644 --- a/test/EFCore.Proxies.Tests/ProxiesApiConsistencyTest.cs +++ b/test/EFCore.Proxies.Tests/ProxiesApiConsistencyTest.cs @@ -24,13 +24,6 @@ protected override Assembly TargetAssembly public class ProxiesApiConsistencyFixture : ApiConsistencyFixtureBase { - public override bool TryGetProviderOptionsDelegate(out Action configureOptions) - { - configureOptions = b => InMemoryTestHelpers.Instance.UseProviderOptions(b); - - return true; - } - public override HashSet FluentApiTypes { get; } = new HashSet { typeof(ProxiesServiceCollectionExtensions) }; } } diff --git a/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs b/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs index 3a14c662ad5..f82f53745fe 100644 --- a/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs +++ b/test/EFCore.Relational.Tests/RelationalApiConsistencyTest.cs @@ -47,12 +47,6 @@ public void Readonly_relational_metadata_methods_have_expected_name() public class RelationalApiConsistencyFixture : ApiConsistencyFixtureBase { - public override bool TryGetProviderOptionsDelegate(out Action configureOptions) - { - configureOptions = null; - return false; - } - private static Dictionary _metadataTypes => new Dictionary { diff --git a/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs b/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs index 726d987b1e8..c76e0bb06db 100644 --- a/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs +++ b/test/EFCore.Specification.Tests/ApiConsistencyTestBase.cs @@ -670,7 +670,13 @@ where ns.StartsWith("Microsoft.Entity", StringComparison.Ordinal) && !it.Name.EndsWith("Dependencies", StringComparison.Ordinal) && (it.GetConstructors().Length != 1 || it.GetConstructors()[0].GetParameters().Length == 0 - || it.GetConstructors()[0].GetParameters()[0].Name != "dependencies") + || it.GetConstructors()[0].GetParameters()[0].Name != "dependencies" + // Check that the parameter has a non-public copy constructor, identifying C# 9 records + || !it.GetConstructors()[0].GetParameters()[0].ParameterType + .GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic) + .Any(c => c.GetParameters() is var parameters + && parameters.Length == 1 + && parameters[0].Name == "original")) select it) .ToList(); @@ -900,8 +906,6 @@ protected ApiConsistencyFixtureBase() Initialize(); } - public abstract bool TryGetProviderOptionsDelegate(out Action configureOptions); - public virtual HashSet FluentApiTypes { get; } = new HashSet(); public virtual Dictionary GenericFluentApiTypes { get; } = new Dictionary diff --git a/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs b/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs index dc985804c16..ff4e8c3ce5d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/SqlServerApiConsistencyTest.cs @@ -28,13 +28,6 @@ protected override Assembly TargetAssembly public class SqlServerApiConsistencyFixture : ApiConsistencyFixtureBase { - public override bool TryGetProviderOptionsDelegate(out Action configureOptions) - { - configureOptions = b => SqlServerTestHelpers.Instance.UseProviderOptions(b); - - return true; - } - public override HashSet FluentApiTypes { get; } = new HashSet { typeof(SqlServerDbContextOptionsBuilder), diff --git a/test/EFCore.SqlServer.Tests/SqlServerNTSApiConsistencyTest.cs b/test/EFCore.SqlServer.Tests/SqlServerNTSApiConsistencyTest.cs index 9d1b0e6a6eb..4581f51dc2e 100644 --- a/test/EFCore.SqlServer.Tests/SqlServerNTSApiConsistencyTest.cs +++ b/test/EFCore.SqlServer.Tests/SqlServerNTSApiConsistencyTest.cs @@ -24,13 +24,6 @@ protected override Assembly TargetAssembly public class SqlServerNTSApiConsistencyFixture : ApiConsistencyFixtureBase { - public override bool TryGetProviderOptionsDelegate(out Action configureOptions) - { - configureOptions = b => SqlServerTestHelpers.Instance.UseProviderOptions(b); - - return true; - } - public override HashSet FluentApiTypes { get; } = new HashSet { typeof(SqlServerNetTopologySuiteDbContextOptionsBuilderExtensions), diff --git a/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs b/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs index 1f155fca278..91364f8c24e 100644 --- a/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/SqliteApiConsistencyTest.cs @@ -26,13 +26,6 @@ protected override Assembly TargetAssembly public class SqliteApiConsistencyFixture : ApiConsistencyFixtureBase { - public override bool TryGetProviderOptionsDelegate(out Action configureOptions) - { - configureOptions = b => SqliteTestHelpers.Instance.UseProviderOptions(b); - - return true; - } - public override HashSet FluentApiTypes { get; } = new HashSet { typeof(SqliteServiceCollectionExtensions), diff --git a/test/EFCore.Sqlite.Tests/SqliteNTSApiConsistencyTest.cs b/test/EFCore.Sqlite.Tests/SqliteNTSApiConsistencyTest.cs index c2a50878203..55d8bb0e908 100644 --- a/test/EFCore.Sqlite.Tests/SqliteNTSApiConsistencyTest.cs +++ b/test/EFCore.Sqlite.Tests/SqliteNTSApiConsistencyTest.cs @@ -24,13 +24,6 @@ protected override Assembly TargetAssembly public class SqliteNTSApiConsistencyFixture : ApiConsistencyFixtureBase { - public override bool TryGetProviderOptionsDelegate(out Action configureOptions) - { - configureOptions = b => SqliteTestHelpers.Instance.UseProviderOptions(b); - - return true; - } - public override HashSet FluentApiTypes { get; } = new HashSet { typeof(SqliteNetTopologySuiteDbContextOptionsBuilderExtensions), diff --git a/test/EFCore.Tests/ApiConsistencyTest.cs b/test/EFCore.Tests/ApiConsistencyTest.cs index fc558042089..1833bc9358d 100644 --- a/test/EFCore.Tests/ApiConsistencyTest.cs +++ b/test/EFCore.Tests/ApiConsistencyTest.cs @@ -37,12 +37,6 @@ protected override void Initialize() base.Initialize(); } - public override bool TryGetProviderOptionsDelegate(out Action configureOptions) - { - configureOptions = null; - return false; - } - public override HashSet FluentApiTypes { get; } = new HashSet { typeof(ModelBuilder), From 598cf758214a9a0a7fe9e5d0fc77bf51137f2ef7 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Thu, 19 Nov 2020 08:55:50 +0200 Subject: [PATCH 2/2] Nullability annotation for storage --- src/EFCore.Abstractions/CommentAttribute.cs | 6 +- .../Internal/CosmosExecutionStrategy.cs | 90 +++++++++--------- .../CosmosExecutionStrategyFactory.cs | 2 +- .../DesignTimeConnectionStringResolver.cs | 8 +- .../RelationalDatabaseFacadeExtensions.cs | 28 +++--- .../Query/ISqlExpressionFactory.cs | 2 +- .../Query/Internal/BufferedDataReader.cs | 2 +- ...mSqlParameterExpandingExpressionVisitor.cs | 2 +- .../Query/QuerySqlGenerator.cs | 4 +- .../Query/SqlExpressionFactory.cs | 4 +- .../Query/SqlExpressions/ExceptExpression.cs | 2 +- .../Query/SqlExpressions/FromSqlExpression.cs | 13 ++- .../SqlExpressions/IntersectExpression.cs | 2 +- .../Query/SqlExpressions/SetOperationBase.cs | 11 +++ .../Query/SqlExpressions/TableExpression.cs | 13 ++- .../TableValuedFunctionExpression.cs | 17 +++- .../Query/SqlExpressions/UnionExpression.cs | 2 +- .../Storage/BoolTypeMapping.cs | 2 + .../Storage/ByteArrayTypeMapping.cs | 2 + .../Storage/ByteTypeMapping.cs | 2 + .../Storage/CharTypeMapping.cs | 2 + .../Storage/DateTimeOffsetTypeMapping.cs | 2 + .../Storage/DateTimeTypeMapping.cs | 2 + .../Storage/DbContextTransactionExtensions.cs | 2 + .../Storage/DecimalTypeMapping.cs | 2 + .../Storage/DoubleTypeMapping.cs | 2 + .../Storage/FloatTypeMapping.cs | 2 + .../Storage/GuidTypeMapping.cs | 2 + .../Storage/IParameterNameGeneratorFactory.cs | 2 + .../Storage/IRawSqlCommandBuilder.cs | 2 + .../Storage/IRelationalCommand.cs | 6 +- .../Storage/IRelationalCommandBuilder.cs | 2 + .../IRelationalCommandBuilderFactory.cs | 2 + .../Storage/IRelationalConnection.cs | 8 +- .../Storage/IRelationalDatabaseCreator.cs | 2 + .../IRelationalDatabaseFacadeDependencies.cs | 2 + .../Storage/IRelationalParameter.cs | 6 +- .../Storage/IRelationalTransactionFactory.cs | 2 + .../Storage/IRelationalTransactionManager.cs | 14 +-- .../Storage/IRelationalTypeMappingSource.cs | 14 +-- .../IRelationalTypeMappingSourcePlugin.cs | 4 +- .../Storage/IRelationalValueBufferFactory.cs | 2 + .../IRelationalValueBufferFactoryFactory.cs | 2 + .../Storage/ISqlGenerationHelper.cs | 6 +- .../Storage/IntTypeMapping.cs | 2 + .../Internal/CompositeRelationalParameter.cs | 16 +--- .../DbParameterCollectionExtensions.cs | 15 +-- .../Internal/DynamicRelationalParameter.cs | 15 +-- .../INamedConnectionStringResolver.cs | 2 + .../Internal/NamedConnectionStringResolver.cs | 4 +- .../NamedConnectionStringResolverBase.cs | 6 +- .../Internal/RawRelationalParameter.cs | 20 ++-- .../Storage/Internal/RawSqlCommandBuilder.cs | 4 +- .../RelationalDatabaseFacadeDependencies.cs | 2 + .../Internal/RelationalParameterBase.cs | 20 +++- .../TypeMappedPropertyRelationalParameter.cs | 4 +- .../Internal/TypeMappedRelationalParameter.cs | 15 +-- .../TypedRelationalValueBufferFactory.cs | 2 + .../Storage/LongTypeMapping.cs | 2 + .../Storage/ParameterNameGenerator.cs | 2 + .../ParameterNameGeneratorDependencies.cs | 2 + .../Storage/ParameterNameGeneratorFactory.cs | 2 + .../Storage/RawSqlCommand.cs | 6 +- src/EFCore.Relational/Storage/ReaderColumn.cs | 19 ++-- .../Storage/ReaderColumn`.cs | 8 +- .../Storage/RelationalCommand.cs | 11 ++- .../Storage/RelationalCommandBuilder.cs | 2 + .../RelationalCommandBuilderDependencies.cs | 2 + .../RelationalCommandBuilderExtensions.cs | 4 +- .../RelationalCommandBuilderFactory.cs | 2 + .../RelationalCommandParameterObject.cs | 26 +++--- .../Storage/RelationalConnection.cs | 56 +++++------ .../RelationalConnectionDependencies.cs | 2 + .../Storage/RelationalDataReader.cs | 6 +- .../Storage/RelationalDatabase.cs | 2 + .../Storage/RelationalDatabaseCreator.cs | 2 + .../RelationalDatabaseCreatorDependencies.cs | 2 + .../Storage/RelationalDatabaseDependencies.cs | 2 + .../RelationalExecutionStrategyExtensions.cs | 12 ++- .../RelationalExecutionStrategyFactory.cs | 6 +- .../Storage/RelationalGeometryTypeMapping.cs | 22 +++-- .../Storage/RelationalSqlGenerationHelper.cs | 8 +- ...lationalSqlGenerationHelperDependencies.cs | 2 + .../Storage/RelationalTransaction.cs | 2 + .../Storage/RelationalTransactionFactory.cs | 2 + ...elationalTransactionFactoryDependencies.cs | 2 + .../Storage/RelationalTypeMapping.cs | 24 ++--- .../Storage/RelationalTypeMappingInfo.cs | 22 +++-- .../Storage/RelationalTypeMappingSource.cs | 52 ++++++----- ...RelationalTypeMappingSourceDependencies.cs | 2 + .../RelationalTypeMappingSourceExtensions.cs | 6 +- ...elationalValueBufferFactoryDependencies.cs | 2 + .../Storage/SByteTypeMapping.cs | 2 + .../Storage/ShortTypeMapping.cs | 2 + .../Storage/StoreTypePostfix.cs | 2 + .../Storage/StringTypeMapping.cs | 2 + .../Storage/TimeSpanTypeMapping.cs | 2 + .../Storage/TypeMaterializationInfo.cs | 93 ++----------------- ...ypedRelationalValueBufferFactoryFactory.cs | 21 +++-- .../Storage/UIntTypeMapping.cs | 2 + .../Storage/ULongTypeMapping.cs | 2 + .../Storage/UShortTypeMapping.cs | 2 + .../RelationalConverterMappingHints.cs | 6 +- .../Internal/SqlServerGeometryTypeMapping.cs | 14 +-- ...NetTopologySuiteTypeMappingSourcePlugin.cs | 8 +- .../SqlServerRetryingExecutionStrategy.cs | 12 ++- .../Storage/Internal/ISqlServerConnection.cs | 2 + .../Internal/SqlServerBoolTypeMapping.cs | 2 + .../Internal/SqlServerByteArrayTypeMapping.cs | 6 +- .../Internal/SqlServerByteTypeMapping.cs | 2 + .../Storage/Internal/SqlServerConnection.cs | 5 +- .../Internal/SqlServerDatabaseCreator.cs | 8 +- .../SqlServerDateTimeOffsetTypeMapping.cs | 2 + .../Internal/SqlServerDateTimeTypeMapping.cs | 2 + .../Internal/SqlServerDecimalTypeMapping.cs | 2 + .../Internal/SqlServerDoubleTypeMapping.cs | 2 + .../Internal/SqlServerExecutionStrategy.cs | 6 +- .../SqlServerExecutionStrategyFactory.cs | 2 + .../Internal/SqlServerFloatTypeMapping.cs | 2 + .../Internal/SqlServerLongTypeMapping.cs | 2 + .../Internal/SqlServerShortTypeMapping.cs | 2 + .../Internal/SqlServerSqlGenerationHelper.cs | 2 + .../SqlServerSqlVariantTypeMapping.cs | 2 + .../Internal/SqlServerStringTypeMapping.cs | 4 +- .../Internal/SqlServerTimeSpanTypeMapping.cs | 2 + .../Storage/Internal/SqlServerTransaction.cs | 2 + .../Internal/SqlServerTransactionFactory.cs | 2 + .../SqlServerTransientExceptionDetector.cs | 4 +- .../Internal/SqlServerTypeMappingSource.cs | 38 ++++---- .../Internal/SqlServerUdtTypeMapping.cs | 16 ++-- .../Internal/ISqliteRelationalConnection.cs | 2 + .../Storage/Internal/SqliteDatabaseCreator.cs | 6 +- .../SqliteDateTimeOffsetTypeMapping.cs | 2 + .../Internal/SqliteDateTimeTypeMapping.cs | 2 + .../Internal/SqliteDecimalTypeMapping.cs | 2 + .../Storage/Internal/SqliteGuidTypeMapping.cs | 2 + .../Internal/SqliteRelationalConnection.cs | 4 +- .../Internal/SqliteSqlGenerationHelper.cs | 6 +- .../Internal/SqliteStringTypeMapping.cs | 2 + .../Internal/SqliteTypeMappingSource.cs | 76 +++++++-------- .../Internal/SqliteULongTypeMapping.cs | 2 + .../Internal/SqliteGeometryTypeMapping.cs | 10 +- ...NetTopologySuiteTypeMappingSourcePlugin.cs | 83 +++++++++-------- src/EFCore/DbUpdateConcurrencyException.cs | 6 +- src/EFCore/DbUpdateException.cs | 8 +- .../Infrastructure/ExpressionExtensions.cs | 2 +- .../Infrastructure/ICurrentDbContext.cs | 2 + .../Internal/CurrentDbContext.cs | 2 + src/EFCore/Storage/CoreTypeMapping.cs | 40 ++++---- src/EFCore/Storage/Database.cs | 2 + src/EFCore/Storage/DatabaseDependencies.cs | 2 + src/EFCore/Storage/DatabaseProvider.cs | 4 +- .../Storage/DatabaseProviderDependencies.cs | 2 + src/EFCore/Storage/ExecutionResult.cs | 2 + src/EFCore/Storage/ExecutionStrategy.cs | 18 ++-- .../Storage/ExecutionStrategyDependencies.cs | 10 +- .../Storage/ExecutionStrategyExtensions.cs | 22 +++-- src/EFCore/Storage/IDatabase.cs | 2 + src/EFCore/Storage/IDatabaseCreator.cs | 2 + .../Storage/IDatabaseFacadeDependencies.cs | 2 + .../IDatabaseFacadeDependenciesAccessor.cs | 2 + src/EFCore/Storage/IDatabaseProvider.cs | 2 + src/EFCore/Storage/IDbContextTransaction.cs | 2 + .../Storage/IDbContextTransactionManager.cs | 4 +- src/EFCore/Storage/IExecutionStrategy.cs | 6 +- .../Storage/IExecutionStrategyFactory.cs | 2 + .../Storage/ITransactionEnlistmentManager.cs | 6 +- src/EFCore/Storage/ITypeMappingSource.cs | 8 +- .../Storage/ITypeMappingSourcePlugin.cs | 4 +- .../Internal/DatabaseFacadeDependencies.cs | 2 + .../Internal/ExecutionStrategyFactory.cs | 2 + src/EFCore/Storage/MaterializationContext.cs | 6 +- .../Storage/NonRetryingExecutionStrategy.cs | 6 +- .../Storage/RetryLimitExceededException.cs | 2 + src/EFCore/Storage/TypeMappingInfo.cs | 10 +- src/EFCore/Storage/TypeMappingSource.cs | 20 ++-- src/EFCore/Storage/TypeMappingSourceBase.cs | 14 +-- .../Storage/TypeMappingSourceDependencies.cs | 2 + src/EFCore/Storage/ValueBuffer.cs | 14 ++- .../ValueConversion/BoolToStringConverter.cs | 6 +- .../BoolToTwoValuesConverter.cs | 6 +- .../ValueConversion/BoolToZeroOneConverter.cs | 6 +- .../ValueConversion/BytesToStringConverter.cs | 11 ++- .../ValueConversion/CastingConverter.cs | 11 ++- .../ValueConversion/CharToStringConverter.cs | 9 +- .../ValueConversion/ConverterMappingHints.cs | 8 +- .../DateTimeOffsetToBinaryConverter.cs | 6 +- .../DateTimeOffsetToBytesConverter.cs | 24 +++-- .../DateTimeOffsetToStringConverter.cs | 7 +- .../DateTimeToBinaryConverter.cs | 6 +- .../DateTimeToStringConverter.cs | 6 +- .../DateTimeToTicksConverter.cs | 4 +- ...faultValueConverterRegistryDependencies.cs | 2 + .../ValueConversion/EnumToNumberConverter.cs | 11 ++- .../ValueConversion/EnumToStringConverter.cs | 6 +- .../ValueConversion/GuidToBytesConverter.cs | 10 +- .../ValueConversion/GuidToStringConverter.cs | 6 +- .../IPAddressToBytesConverter.cs | 15 ++- .../IPAddressToStringConverter.cs | 18 ++-- .../IValueConverterSelector.cs | 4 +- .../Internal/CompositeValueConverter.cs | 4 +- .../Internal/StringCharConverter.cs | 4 +- .../Internal/StringDateTimeConverter.cs | 7 +- .../Internal/StringDateTimeOffsetConverter.cs | 7 +- .../Internal/StringEnumConverter.cs | 6 +- .../Internal/StringGuidConverter.cs | 8 +- .../Internal/StringNumberConverter.cs | 12 ++- .../Internal/StringTimeSpanConverter.cs | 7 +- .../Internal/StringUriConverter.cs | 10 +- .../ValueConversion/NumberToBytesConverter.cs | 26 +++--- .../NumberToStringConverter.cs | 7 +- .../PhysicalAddressToBytesConverter.cs | 18 ++-- .../PhysicalAddressToStringConverter.cs | 19 ++-- .../ValueConversion/StringToBoolConverter.cs | 6 +- .../ValueConversion/StringToBytesConverter.cs | 11 ++- .../ValueConversion/StringToCharConverter.cs | 9 +- .../StringToDateTimeConverter.cs | 6 +- .../StringToDateTimeOffsetConverter.cs | 7 +- .../ValueConversion/StringToEnumConverter.cs | 6 +- .../ValueConversion/StringToGuidConverter.cs | 6 +- .../StringToNumberConverter.cs | 7 +- .../StringToTimeSpanConverter.cs | 6 +- .../ValueConversion/StringToUriConverter.cs | 6 +- .../TimeSpanToStringConverter.cs | 6 +- .../TimeSpanToTicksConverter.cs | 6 +- .../ValueConversion/UriToStringConverter.cs | 6 +- .../Storage/ValueConversion/ValueConverter.cs | 16 ++-- .../ValueConversion/ValueConverterInfo.cs | 6 +- .../ValueConversion/ValueConverterSelector.cs | 67 ++++++------- .../ValueConversion/ValueConverter`.cs | 16 ++-- 230 files changed, 1161 insertions(+), 836 deletions(-) diff --git a/src/EFCore.Abstractions/CommentAttribute.cs b/src/EFCore.Abstractions/CommentAttribute.cs index b67f738d522..85e8e67cce8 100644 --- a/src/EFCore.Abstractions/CommentAttribute.cs +++ b/src/EFCore.Abstractions/CommentAttribute.cs @@ -8,7 +8,7 @@ namespace Microsoft.EntityFrameworkCore { /// - /// Marks a class, property or field with a comment which will be included in the SQL sent to the database . + /// Marks a class, property or field with a comment to be set on the corresponding database table or column. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field)] public sealed class CommentAttribute : Attribute @@ -16,7 +16,7 @@ public sealed class CommentAttribute : Attribute /// /// Initializes a new instance of the class. /// - /// The comment. + /// The comment. public CommentAttribute([NotNull] string comment) { Check.NotEmpty(comment, nameof(comment)); @@ -25,7 +25,7 @@ public CommentAttribute([NotNull] string comment) } /// - /// The Comment + /// The comment to be configured. /// public string Comment { get; } } diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosExecutionStrategy.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosExecutionStrategy.cs index 452072f447e..7083fd93a9c 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosExecutionStrategy.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosExecutionStrategy.cs @@ -9,6 +9,8 @@ using Microsoft.Azure.Cosmos; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal { /// @@ -97,24 +99,15 @@ public CosmosExecutionStrategy([NotNull] ExecutionStrategyDependencies dependenc /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override bool ShouldRetryOn(Exception exception) + protected override bool ShouldRetryOn(Exception? exception) { - if (exception is CosmosException cosmosException) + return exception switch { - return IsTransient(cosmosException.StatusCode); - } - - if (exception is HttpException httpException) - { - return IsTransient(httpException.Response.StatusCode); - } - - if (exception is WebException webException) - { - return IsTransient(((HttpWebResponse)webException.Response).StatusCode); - } - - return false; + CosmosException cosmosException => IsTransient(cosmosException.StatusCode), + HttpException httpException => IsTransient(httpException.Response.StatusCode), + WebException webException => IsTransient(((HttpWebResponse)webException.Response!).StatusCode), + _ => false + }; static bool IsTransient(HttpStatusCode statusCode) => statusCode == HttpStatusCode.ServiceUnavailable @@ -136,47 +129,54 @@ static bool IsTransient(HttpStatusCode statusCode) ?? baseDelay; } - private static TimeSpan? GetDelayFromException(Exception exception) + private static TimeSpan? GetDelayFromException(Exception? exception) { - if (exception is CosmosException cosmosException) + switch (exception) { - return cosmosException.RetryAfter; - } + case CosmosException cosmosException: + return cosmosException.RetryAfter; - if (exception is HttpException httpException) - { - if (httpException.Response.Headers.TryGetValues("x-ms-retry-after-ms", out var values) - && TryParseMsRetryAfter(values.FirstOrDefault(), out var delay)) + case HttpException httpException: { - return delay; + if (httpException.Response.Headers.TryGetValues("x-ms-retry-after-ms", out var values) + && TryParseMsRetryAfter(values.FirstOrDefault(), out var delay)) + { + return delay; + } + + if (httpException.Response.Headers.TryGetValues("Retry-After", out values) + && TryParseRetryAfter(values.FirstOrDefault(), out delay)) + { + return delay; + } + + return null; } - if (httpException.Response.Headers.TryGetValues("Retry-After", out values) - && TryParseRetryAfter(values.FirstOrDefault(), out delay)) + case WebException webException: { - return delay; - } - } + var response = (HttpWebResponse)webException.Response!; - if (exception is WebException webException) - { - var response = (HttpWebResponse)webException.Response; + var delayString = response.Headers.GetValues("x-ms-retry-after-ms")?.FirstOrDefault(); + if (TryParseMsRetryAfter(delayString, out var delay)) + { + return delay; + } - var delayString = response.Headers.GetValues("x-ms-retry-after-ms")?.FirstOrDefault(); - if (TryParseMsRetryAfter(delayString, out var delay)) - { - return delay; - } + delayString = response.Headers.GetValues("Retry-After")?.FirstOrDefault(); + if (TryParseRetryAfter(delayString, out delay)) + { + return delay; + } - delayString = response.Headers.GetValues("Retry-After")?.FirstOrDefault(); - if (TryParseRetryAfter(delayString, out delay)) - { - return delay; + return null; } + + default: + return null; } - return null; - static bool TryParseMsRetryAfter(string delayString, out TimeSpan delay) + static bool TryParseMsRetryAfter(string? delayString, out TimeSpan delay) { delay = default; if (delayString == null) @@ -193,7 +193,7 @@ static bool TryParseMsRetryAfter(string delayString, out TimeSpan delay) return false; } - static bool TryParseRetryAfter(string delayString, out TimeSpan delay) + static bool TryParseRetryAfter(string? delayString, out TimeSpan delay) { delay = default; if (delayString == null) diff --git a/src/EFCore.Cosmos/Storage/Internal/CosmosExecutionStrategyFactory.cs b/src/EFCore.Cosmos/Storage/Internal/CosmosExecutionStrategyFactory.cs index b8f6dd6da78..39eab05d715 100644 --- a/src/EFCore.Cosmos/Storage/Internal/CosmosExecutionStrategyFactory.cs +++ b/src/EFCore.Cosmos/Storage/Internal/CosmosExecutionStrategyFactory.cs @@ -40,7 +40,7 @@ public CosmosExecutionStrategyFactory([NotNull] ExecutionStrategyDependencies de Dependencies = dependencies; - _createExecutionStrategy = dependencies.Options?.FindExtension()?.ExecutionStrategyFactory + _createExecutionStrategy = dependencies.Options.FindExtension()?.ExecutionStrategyFactory ?? CreateDefaultStrategy; } diff --git a/src/EFCore.Design/Design/Internal/DesignTimeConnectionStringResolver.cs b/src/EFCore.Design/Design/Internal/DesignTimeConnectionStringResolver.cs index 9c0aaedba2e..e2877ed6f8c 100644 --- a/src/EFCore.Design/Design/Internal/DesignTimeConnectionStringResolver.cs +++ b/src/EFCore.Design/Design/Internal/DesignTimeConnectionStringResolver.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Storage.Internal; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Design.Internal { /// @@ -24,7 +26,7 @@ namespace Microsoft.EntityFrameworkCore.Design.Internal /// public class DesignTimeConnectionStringResolver : NamedConnectionStringResolverBase { - private readonly Func _applicationServiceProviderAccessor; + private readonly Func? _applicationServiceProviderAccessor; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -32,7 +34,7 @@ public class DesignTimeConnectionStringResolver : NamedConnectionStringResolverB /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public DesignTimeConnectionStringResolver([CanBeNull] Func applicationServiceProviderAccessor) + public DesignTimeConnectionStringResolver([CanBeNull] Func? applicationServiceProviderAccessor) { _applicationServiceProviderAccessor = applicationServiceProviderAccessor; } @@ -43,7 +45,7 @@ public DesignTimeConnectionStringResolver([CanBeNull] Func app /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override IServiceProvider ApplicationServiceProvider + protected override IServiceProvider? ApplicationServiceProvider => _applicationServiceProviderAccessor?.Invoke(); } } diff --git a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs index fe4cd93385f..1fa78ea0c02 100644 --- a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs @@ -16,6 +16,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + // ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore { @@ -177,7 +179,7 @@ public static int ExecuteSqlRaw( public static int ExecuteSqlInterpolated( [NotNull] this DatabaseFacade databaseFacade, [NotNull] FormattableString sql) - => ExecuteSqlRaw(databaseFacade, sql.Format, sql.GetArguments()); + => ExecuteSqlRaw(databaseFacade, sql.Format, sql.GetArguments()!); /// /// @@ -274,7 +276,7 @@ public static Task ExecuteSqlInterpolatedAsync( [NotNull] this DatabaseFacade databaseFacade, [NotNull] FormattableString sql, CancellationToken cancellationToken = default) - => ExecuteSqlRawAsync(databaseFacade, sql.Format, sql.GetArguments(), cancellationToken); + => ExecuteSqlRawAsync(databaseFacade, sql.Format, sql.GetArguments()!, cancellationToken); /// /// @@ -442,7 +444,7 @@ public static DbConnection GetDbConnection([NotNull] this DatabaseFacade databas /// /// The for the context. /// The connection. - public static void SetDbConnection([NotNull] this DatabaseFacade databaseFacade, [CanBeNull] DbConnection connection) + public static void SetDbConnection([NotNull] this DatabaseFacade databaseFacade, [CanBeNull] DbConnection? connection) => GetFacadeDependencies(databaseFacade).RelationalConnection.DbConnection = connection; /// @@ -450,7 +452,7 @@ public static void SetDbConnection([NotNull] this DatabaseFacade databaseFacade, /// /// The for the context. /// The connection string. - public static string GetConnectionString([NotNull] this DatabaseFacade databaseFacade) + public static string? GetConnectionString([NotNull] this DatabaseFacade databaseFacade) => GetFacadeDependencies(databaseFacade).RelationalConnection.ConnectionString; /// @@ -463,7 +465,7 @@ public static string GetConnectionString([NotNull] this DatabaseFacade databaseF /// /// The for the context. /// The connection string. - public static void SetConnectionString([NotNull] this DatabaseFacade databaseFacade, [CanBeNull] string connectionString) + public static void SetConnectionString([NotNull] this DatabaseFacade databaseFacade, [CanBeNull] string? connectionString) => GetFacadeDependencies(databaseFacade).RelationalConnection.ConnectionString = connectionString; /// @@ -552,9 +554,9 @@ public static Task BeginTransactionAsync( /// The for the context. /// The to use. /// A that encapsulates the given transaction. - public static IDbContextTransaction UseTransaction( + public static IDbContextTransaction? UseTransaction( [NotNull] this DatabaseFacade databaseFacade, - [CanBeNull] DbTransaction transaction) + [CanBeNull] DbTransaction? transaction) => databaseFacade.UseTransaction(transaction, Guid.NewGuid()); /// @@ -564,9 +566,9 @@ public static IDbContextTransaction UseTransaction( /// The to use. /// The unique identifier for the transaction. /// A that encapsulates the given transaction. - public static IDbContextTransaction UseTransaction( + public static IDbContextTransaction? UseTransaction( [NotNull] this DatabaseFacade databaseFacade, - [CanBeNull] DbTransaction transaction, + [CanBeNull] DbTransaction? transaction, Guid transactionId) { var transactionManager = GetTransactionManager(databaseFacade); @@ -587,9 +589,9 @@ public static IDbContextTransaction UseTransaction( /// A to observe while waiting for the task to complete. /// A containing the for the given transaction. /// If the is canceled. - public static Task UseTransactionAsync( + public static Task UseTransactionAsync( [NotNull] this DatabaseFacade databaseFacade, - [CanBeNull] DbTransaction transaction, + [CanBeNull] DbTransaction? transaction, CancellationToken cancellationToken = default) => databaseFacade.UseTransactionAsync(transaction, Guid.NewGuid(), cancellationToken); @@ -602,9 +604,9 @@ public static Task UseTransactionAsync( /// A to observe while waiting for the task to complete. /// A containing the for the given transaction. /// If the is canceled. - public static Task UseTransactionAsync( + public static Task UseTransactionAsync( [NotNull] this DatabaseFacade databaseFacade, - [CanBeNull] DbTransaction transaction, + [CanBeNull] DbTransaction? transaction, Guid transactionId, CancellationToken cancellationToken = default) { diff --git a/src/EFCore.Relational/Query/ISqlExpressionFactory.cs b/src/EFCore.Relational/Query/ISqlExpressionFactory.cs index 1f56ab412fe..fba7226e162 100644 --- a/src/EFCore.Relational/Query/ISqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/ISqlExpressionFactory.cs @@ -41,7 +41,7 @@ public interface ISqlExpressionFactory /// The CLR type. /// The type mapping, or if none was found. [Obsolete("Use IRelationalTypeMappingSource directly.")] - RelationalTypeMapping FindMapping([NotNull] Type type); + RelationalTypeMapping? FindMapping([NotNull] Type type); /// /// Applies type mapping to the given . diff --git a/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs b/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs index c05e9a0b456..5af27c0298b 100644 --- a/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs +++ b/src/EFCore.Relational/Query/Internal/BufferedDataReader.cs @@ -1270,7 +1270,7 @@ private void InitializeFields() for (var i = 0; i < _columns.Count; i++) { var column = _columns[i]; - if (!readerColumns.TryGetValue(column.Name, out var ordinal)) + if (!readerColumns.TryGetValue(column.Name!, out var ordinal)) { throw new InvalidOperationException(RelationalStrings.FromSqlMissingColumn(column.Name)); } diff --git a/src/EFCore.Relational/Query/Internal/FromSqlParameterExpandingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/FromSqlParameterExpandingExpressionVisitor.cs index d36d2774288..68c259b2229 100644 --- a/src/EFCore.Relational/Query/Internal/FromSqlParameterExpandingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/Internal/FromSqlParameterExpandingExpressionVisitor.cs @@ -129,7 +129,7 @@ public virtual SelectExpression Expand( } updatedFromSql = fromSql.Update( - Expression.Constant(new CompositeRelationalParameter(parameterExpression.Name, subParameters))); + Expression.Constant(new CompositeRelationalParameter(parameterExpression.Name!, subParameters))); _visitedFromSqlExpressions[fromSql] = updatedFromSql; break; diff --git a/src/EFCore.Relational/Query/QuerySqlGenerator.cs b/src/EFCore.Relational/Query/QuerySqlGenerator.cs index 91949ff4cf4..8366335dfbb 100644 --- a/src/EFCore.Relational/Query/QuerySqlGenerator.cs +++ b/src/EFCore.Relational/Query/QuerySqlGenerator.cs @@ -331,7 +331,7 @@ protected override Expression VisitColumn(ColumnExpression columnExpression) Check.NotNull(columnExpression, nameof(columnExpression)); _relationalCommandBuilder - .Append(_sqlGenerationHelper.DelimitIdentifier(columnExpression.Table.Alias)) + .Append(_sqlGenerationHelper.DelimitIdentifier(columnExpression.Table.Alias!)) .Append(".") .Append(_sqlGenerationHelper.DelimitIdentifier(columnExpression.Name)); @@ -572,7 +572,7 @@ protected override Expression VisitSqlParameter(SqlParameterExpression sqlParame _relationalCommandBuilder.AddParameter( sqlParameterExpression.Name, parameterNameInCommand, - sqlParameterExpression.TypeMapping, + sqlParameterExpression.TypeMapping!, sqlParameterExpression.IsNullable); } diff --git a/src/EFCore.Relational/Query/SqlExpressionFactory.cs b/src/EFCore.Relational/Query/SqlExpressionFactory.cs index 0ccb5368495..33bc73aca1b 100644 --- a/src/EFCore.Relational/Query/SqlExpressionFactory.cs +++ b/src/EFCore.Relational/Query/SqlExpressionFactory.cs @@ -34,7 +34,7 @@ public SqlExpressionFactory([NotNull] SqlExpressionFactoryDependencies dependenc Check.NotNull(dependencies, nameof(dependencies)); _typeMappingSource = dependencies.TypeMappingSource; - _boolTypeMapping = _typeMappingSource.FindMapping(typeof(bool)); + _boolTypeMapping = _typeMappingSource.FindMapping(typeof(bool))!; } /// @@ -1017,7 +1017,7 @@ public virtual RelationalTypeMapping GetTypeMappingForValue(object? value) /// [Obsolete("Use IRelationalTypeMappingSource directly.")] - public virtual RelationalTypeMapping FindMapping(Type type) + public virtual RelationalTypeMapping? FindMapping(Type type) => _typeMappingSource.FindMapping(Check.NotNull(type, nameof(type))); } } diff --git a/src/EFCore.Relational/Query/SqlExpressions/ExceptExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/ExceptExpression.cs index 7b4f55d045e..d5cb36e710c 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/ExceptExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/ExceptExpression.cs @@ -61,7 +61,7 @@ public virtual ExceptExpression Update([NotNull] SelectExpression source1, [NotN Check.NotNull(source2, nameof(source2)); return source1 != Source1 || source2 != Source2 - ? new ExceptExpression(Alias!, source1, source2, IsDistinct) + ? new ExceptExpression(Alias, source1, source2, IsDistinct) : this; } diff --git a/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs index 08738af05d1..b7e9d52ecb1 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/FromSqlExpression.cs @@ -5,6 +5,7 @@ using System.Linq.Expressions; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +using CA = System.Diagnostics.CodeAnalysis; #nullable enable @@ -54,6 +55,16 @@ public FromSqlExpression([NotNull] string alias, [NotNull] string sql, [NotNull] Arguments = arguments; } + /// + /// The alias assigned to this table source. + /// + [CA.NotNull] + public override string? Alias + { + get => base.Alias!; + internal set => base.Alias = value; + } + /// /// The user-provided custom SQL for the table source. /// @@ -75,7 +86,7 @@ public virtual FromSqlExpression Update([NotNull] Expression arguments) Check.NotNull(arguments, nameof(arguments)); return arguments != Arguments - ? new FromSqlExpression(Alias!, Sql, arguments) + ? new FromSqlExpression(Alias, Sql, arguments) : this; } diff --git a/src/EFCore.Relational/Query/SqlExpressions/IntersectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/IntersectExpression.cs index 2639116cc55..5e852327ceb 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/IntersectExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/IntersectExpression.cs @@ -61,7 +61,7 @@ public virtual IntersectExpression Update([NotNull] SelectExpression source1, [N Check.NotNull(source2, nameof(source2)); return source1 != Source1 || source2 != Source2 - ? new IntersectExpression(Alias!, source1, source2, IsDistinct) + ? new IntersectExpression(Alias, source1, source2, IsDistinct) : this; } diff --git a/src/EFCore.Relational/Query/SqlExpressions/SetOperationBase.cs b/src/EFCore.Relational/Query/SqlExpressions/SetOperationBase.cs index df33268023c..bb4294130f3 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SetOperationBase.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SetOperationBase.cs @@ -4,6 +4,7 @@ using System; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +using CA = System.Diagnostics.CodeAnalysis; #nullable enable @@ -42,6 +43,16 @@ protected SetOperationBase( Source2 = source2; } + /// + /// The alias assigned to this table source. + /// + [CA.NotNull] + public override string? Alias + { + get => base.Alias!; + internal set => base.Alias = value; + } + /// /// The bool value indicating whether result will remove duplicate rows. /// diff --git a/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs index 77ae36a006e..17b743bc59d 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/TableExpression.cs @@ -5,6 +5,7 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; +using CA = System.Diagnostics.CodeAnalysis; #nullable enable @@ -40,7 +41,17 @@ protected override void Print(ExpressionPrinter expressionPrinter) expressionPrinter.Append(Schema).Append("."); } - expressionPrinter.Append(Name).Append(" AS ").Append(Alias!); + expressionPrinter.Append(Name).Append(" AS ").Append(Alias); + } + + /// + /// The alias assigned to this table source. + /// + [CA.NotNull] + public override string? Alias + { + get => base.Alias!; + internal set => base.Alias = value; } /// diff --git a/src/EFCore.Relational/Query/SqlExpressions/TableValuedFunctionExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/TableValuedFunctionExpression.cs index 82d49816815..d09f24742cd 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/TableValuedFunctionExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/TableValuedFunctionExpression.cs @@ -8,6 +8,7 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; +using CA = System.Diagnostics.CodeAnalysis; #nullable enable @@ -44,6 +45,16 @@ private TableValuedFunctionExpression(string alias, IStoreFunction storeFunction Arguments = arguments; } + /// + /// The alias assigned to this table source. + /// + [CA.NotNull] + public override string? Alias + { + get => base.Alias!; + internal set => base.Alias = value; + } + /// /// The store function. /// @@ -68,7 +79,7 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) } return changed - ? new TableValuedFunctionExpression(Alias!, StoreFunction, arguments) + ? new TableValuedFunctionExpression(Alias, StoreFunction, arguments) : this; } @@ -83,7 +94,7 @@ public virtual TableValuedFunctionExpression Update([NotNull] IReadOnlyList diff --git a/src/EFCore.Relational/Query/SqlExpressions/UnionExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/UnionExpression.cs index 31dad14d7a2..50f2af4c8c3 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/UnionExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/UnionExpression.cs @@ -61,7 +61,7 @@ public virtual UnionExpression Update([NotNull] SelectExpression source1, [NotNu Check.NotNull(source2, nameof(source2)); return source1 != Source1 || source2 != Source2 - ? new UnionExpression(Alias!, source1, source2, IsDistinct) + ? new UnionExpression(Alias, source1, source2, IsDistinct) : this; } diff --git a/src/EFCore.Relational/Storage/BoolTypeMapping.cs b/src/EFCore.Relational/Storage/BoolTypeMapping.cs index d33b1543eb8..4d5448432c7 100644 --- a/src/EFCore.Relational/Storage/BoolTypeMapping.cs +++ b/src/EFCore.Relational/Storage/BoolTypeMapping.cs @@ -4,6 +4,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/ByteArrayTypeMapping.cs b/src/EFCore.Relational/Storage/ByteArrayTypeMapping.cs index 26c73b340a3..83948582ac9 100644 --- a/src/EFCore.Relational/Storage/ByteArrayTypeMapping.cs +++ b/src/EFCore.Relational/Storage/ByteArrayTypeMapping.cs @@ -7,6 +7,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/ByteTypeMapping.cs b/src/EFCore.Relational/Storage/ByteTypeMapping.cs index 622f3d719cf..bee8604fdf1 100644 --- a/src/EFCore.Relational/Storage/ByteTypeMapping.cs +++ b/src/EFCore.Relational/Storage/ByteTypeMapping.cs @@ -4,6 +4,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/CharTypeMapping.cs b/src/EFCore.Relational/Storage/CharTypeMapping.cs index 3a39cb6ece2..95352525e9a 100644 --- a/src/EFCore.Relational/Storage/CharTypeMapping.cs +++ b/src/EFCore.Relational/Storage/CharTypeMapping.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/DateTimeOffsetTypeMapping.cs b/src/EFCore.Relational/Storage/DateTimeOffsetTypeMapping.cs index e8ffe06fdfc..f482ed17878 100644 --- a/src/EFCore.Relational/Storage/DateTimeOffsetTypeMapping.cs +++ b/src/EFCore.Relational/Storage/DateTimeOffsetTypeMapping.cs @@ -5,6 +5,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/DateTimeTypeMapping.cs b/src/EFCore.Relational/Storage/DateTimeTypeMapping.cs index 1b527934562..479e0a122e2 100644 --- a/src/EFCore.Relational/Storage/DateTimeTypeMapping.cs +++ b/src/EFCore.Relational/Storage/DateTimeTypeMapping.cs @@ -5,6 +5,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/DbContextTransactionExtensions.cs b/src/EFCore.Relational/Storage/DbContextTransactionExtensions.cs index 9bc0c70d159..2a60c544b22 100644 --- a/src/EFCore.Relational/Storage/DbContextTransactionExtensions.cs +++ b/src/EFCore.Relational/Storage/DbContextTransactionExtensions.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/DecimalTypeMapping.cs b/src/EFCore.Relational/Storage/DecimalTypeMapping.cs index 3dcf0e551b6..30ff196428b 100644 --- a/src/EFCore.Relational/Storage/DecimalTypeMapping.cs +++ b/src/EFCore.Relational/Storage/DecimalTypeMapping.cs @@ -4,6 +4,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/DoubleTypeMapping.cs b/src/EFCore.Relational/Storage/DoubleTypeMapping.cs index 3d724de87aa..4d113aa5b4f 100644 --- a/src/EFCore.Relational/Storage/DoubleTypeMapping.cs +++ b/src/EFCore.Relational/Storage/DoubleTypeMapping.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.ChangeTracking; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/FloatTypeMapping.cs b/src/EFCore.Relational/Storage/FloatTypeMapping.cs index 4a4c931ac81..d3fec08707d 100644 --- a/src/EFCore.Relational/Storage/FloatTypeMapping.cs +++ b/src/EFCore.Relational/Storage/FloatTypeMapping.cs @@ -7,6 +7,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.ChangeTracking; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/GuidTypeMapping.cs b/src/EFCore.Relational/Storage/GuidTypeMapping.cs index 6e9eb868a83..e9fbbe77572 100644 --- a/src/EFCore.Relational/Storage/GuidTypeMapping.cs +++ b/src/EFCore.Relational/Storage/GuidTypeMapping.cs @@ -5,6 +5,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/IParameterNameGeneratorFactory.cs b/src/EFCore.Relational/Storage/IParameterNameGeneratorFactory.cs index 8f03f8b6614..f626766737f 100644 --- a/src/EFCore.Relational/Storage/IParameterNameGeneratorFactory.cs +++ b/src/EFCore.Relational/Storage/IParameterNameGeneratorFactory.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/IRawSqlCommandBuilder.cs b/src/EFCore.Relational/Storage/IRawSqlCommandBuilder.cs index 08ecfb28bce..c61abb9dcf2 100644 --- a/src/EFCore.Relational/Storage/IRawSqlCommandBuilder.cs +++ b/src/EFCore.Relational/Storage/IRawSqlCommandBuilder.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/IRelationalCommand.cs b/src/EFCore.Relational/Storage/IRelationalCommand.cs index 4414f4ce16d..9590c3ab836 100644 --- a/src/EFCore.Relational/Storage/IRelationalCommand.cs +++ b/src/EFCore.Relational/Storage/IRelationalCommand.cs @@ -8,6 +8,8 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Diagnostics; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -56,7 +58,7 @@ Task ExecuteNonQueryAsync( /// /// Parameters for this method. /// The result of the command. - object ExecuteScalar(RelationalCommandParameterObject parameterObject); + object? ExecuteScalar(RelationalCommandParameterObject parameterObject); /// /// Asynchronously executes the command with a single scalar result. @@ -67,7 +69,7 @@ Task ExecuteNonQueryAsync( /// A task that represents the asynchronous operation. The task result contains the result of the command. /// /// If the is canceled. - Task ExecuteScalarAsync( + Task ExecuteScalarAsync( RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken = default); diff --git a/src/EFCore.Relational/Storage/IRelationalCommandBuilder.cs b/src/EFCore.Relational/Storage/IRelationalCommandBuilder.cs index 41e1e5f2c09..5e26f761e94 100644 --- a/src/EFCore.Relational/Storage/IRelationalCommandBuilder.cs +++ b/src/EFCore.Relational/Storage/IRelationalCommandBuilder.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/IRelationalCommandBuilderFactory.cs b/src/EFCore.Relational/Storage/IRelationalCommandBuilderFactory.cs index 9f654e499d1..1922c8f50e8 100644 --- a/src/EFCore.Relational/Storage/IRelationalCommandBuilderFactory.cs +++ b/src/EFCore.Relational/Storage/IRelationalCommandBuilderFactory.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/IRelationalConnection.cs b/src/EFCore.Relational/Storage/IRelationalConnection.cs index bd5e111ff5d..285960e4f30 100644 --- a/src/EFCore.Relational/Storage/IRelationalConnection.cs +++ b/src/EFCore.Relational/Storage/IRelationalConnection.cs @@ -7,6 +7,9 @@ using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable namespace Microsoft.EntityFrameworkCore.Storage { @@ -30,7 +33,7 @@ public interface IRelationalConnection : IRelationalTransactionManager, IDisposa /// /// Gets or sets the connection string for the database. /// - string ConnectionString { get; [param: CanBeNull] set; } + string? ConnectionString { get; [param: CanBeNull] set; } /// /// @@ -43,6 +46,7 @@ public interface IRelationalConnection : IRelationalTransactionManager, IDisposa /// Note that the connection must be disposed by application code since it was not created by Entity Framework. /// /// + [CA.AllowNull] DbConnection DbConnection { get; [param: CanBeNull] set; } /// @@ -99,7 +103,7 @@ public interface IRelationalConnection : IRelationalTransactionManager, IDisposa /// /// Gets the current transaction. /// - new IDbContextTransaction CurrentTransaction { get; } + new IDbContextTransaction? CurrentTransaction { get; } /// /// Gets a semaphore used to serialize access to this connection. diff --git a/src/EFCore.Relational/Storage/IRelationalDatabaseCreator.cs b/src/EFCore.Relational/Storage/IRelationalDatabaseCreator.cs index 075ba50a7cb..099b02b5d4d 100644 --- a/src/EFCore.Relational/Storage/IRelationalDatabaseCreator.cs +++ b/src/EFCore.Relational/Storage/IRelationalDatabaseCreator.cs @@ -6,6 +6,8 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/IRelationalDatabaseFacadeDependencies.cs b/src/EFCore.Relational/Storage/IRelationalDatabaseFacadeDependencies.cs index aa949d5bb02..f0f8e7f9a17 100644 --- a/src/EFCore.Relational/Storage/IRelationalDatabaseFacadeDependencies.cs +++ b/src/EFCore.Relational/Storage/IRelationalDatabaseFacadeDependencies.cs @@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/IRelationalParameter.cs b/src/EFCore.Relational/Storage/IRelationalParameter.cs index 75b71c384de..e056baafcdb 100644 --- a/src/EFCore.Relational/Storage/IRelationalParameter.cs +++ b/src/EFCore.Relational/Storage/IRelationalParameter.cs @@ -5,6 +5,8 @@ using System.Data.Common; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -30,13 +32,13 @@ public interface IRelationalParameter /// /// The command to add the parameter to. /// The value to be assigned to the parameter. - void AddDbParameter([NotNull] DbCommand command, [CanBeNull] object value); + void AddDbParameter([NotNull] DbCommand command, [CanBeNull] object? value); /// /// Adds the parameter as a to a . /// /// The command to add the parameter to. /// The map of parameter values - void AddDbParameter([NotNull] DbCommand command, [NotNull] IReadOnlyDictionary parameterValues); + void AddDbParameter([NotNull] DbCommand command, [NotNull] IReadOnlyDictionary parameterValues); } } diff --git a/src/EFCore.Relational/Storage/IRelationalTransactionFactory.cs b/src/EFCore.Relational/Storage/IRelationalTransactionFactory.cs index ba3f0c736d9..9585879c8ef 100644 --- a/src/EFCore.Relational/Storage/IRelationalTransactionFactory.cs +++ b/src/EFCore.Relational/Storage/IRelationalTransactionFactory.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/IRelationalTransactionManager.cs b/src/EFCore.Relational/Storage/IRelationalTransactionManager.cs index 05dea82956f..f33027e6b26 100644 --- a/src/EFCore.Relational/Storage/IRelationalTransactionManager.cs +++ b/src/EFCore.Relational/Storage/IRelationalTransactionManager.cs @@ -9,6 +9,8 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -49,7 +51,7 @@ public interface IRelationalTransactionManager : IDbContextTransactionManager /// /// The transaction to be used. /// An instance of that wraps the provided transaction. - IDbContextTransaction UseTransaction([CanBeNull] DbTransaction transaction); + IDbContextTransaction? UseTransaction([CanBeNull] DbTransaction? transaction); /// /// Specifies an existing to be used for database operations. @@ -57,7 +59,7 @@ public interface IRelationalTransactionManager : IDbContextTransactionManager /// The transaction to be used. /// The unique identifier for the transaction. /// An instance of that wraps the provided transaction. - IDbContextTransaction UseTransaction([CanBeNull] DbTransaction transaction, Guid transactionId); + IDbContextTransaction? UseTransaction([CanBeNull] DbTransaction? transaction, Guid transactionId); /// /// Specifies an existing to be used for database operations. @@ -66,8 +68,8 @@ public interface IRelationalTransactionManager : IDbContextTransactionManager /// A to observe while waiting for the task to complete. /// An instance of that wraps the provided transaction. /// If the is canceled. - Task UseTransactionAsync( - [CanBeNull] DbTransaction transaction, + Task UseTransactionAsync( + [CanBeNull] DbTransaction? transaction, CancellationToken cancellationToken = default); /// @@ -78,8 +80,8 @@ Task UseTransactionAsync( /// A to observe while waiting for the task to complete. /// An instance of that wraps the provided transaction. /// If the is canceled. - Task UseTransactionAsync( - [CanBeNull] DbTransaction transaction, + Task UseTransactionAsync( + [CanBeNull] DbTransaction? transaction, Guid transactionId, CancellationToken cancellationToken = default); } diff --git a/src/EFCore.Relational/Storage/IRelationalTypeMappingSource.cs b/src/EFCore.Relational/Storage/IRelationalTypeMappingSource.cs index 4b3599457f1..4540516f3ba 100644 --- a/src/EFCore.Relational/Storage/IRelationalTypeMappingSource.cs +++ b/src/EFCore.Relational/Storage/IRelationalTypeMappingSource.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -34,7 +36,7 @@ public interface IRelationalTypeMappingSource : ITypeMappingSource /// /// The property. /// The type mapping, or if none was found. - new RelationalTypeMapping FindMapping([NotNull] IProperty property); + new RelationalTypeMapping? FindMapping([NotNull] IProperty property); /// /// @@ -48,7 +50,7 @@ public interface IRelationalTypeMappingSource : ITypeMappingSource /// /// The field or property. /// The type mapping, or if none was found. - new RelationalTypeMapping FindMapping([NotNull] MemberInfo member); + new RelationalTypeMapping? FindMapping([NotNull] MemberInfo member); /// /// @@ -62,7 +64,7 @@ public interface IRelationalTypeMappingSource : ITypeMappingSource /// /// The CLR type. /// The type mapping, or if none was found. - new RelationalTypeMapping FindMapping([NotNull] Type type); + new RelationalTypeMapping? FindMapping([NotNull] Type type); /// /// @@ -75,7 +77,7 @@ public interface IRelationalTypeMappingSource : ITypeMappingSource /// /// The database type name. /// The type mapping, or if none was found. - RelationalTypeMapping FindMapping([NotNull] string storeTypeName); + RelationalTypeMapping? FindMapping([NotNull] string storeTypeName); /// /// @@ -99,9 +101,9 @@ public interface IRelationalTypeMappingSource : ITypeMappingSource /// Specifies a precision for the mapping, or for default. /// Specifies a scale for the mapping, or for default. /// The type mapping, or if none was found. - RelationalTypeMapping FindMapping( + RelationalTypeMapping? FindMapping( [NotNull] Type type, - [CanBeNull] string storeTypeName, + [CanBeNull] string? storeTypeName, bool keyOrIndex = false, bool? unicode = null, int? size = null, diff --git a/src/EFCore.Relational/Storage/IRelationalTypeMappingSourcePlugin.cs b/src/EFCore.Relational/Storage/IRelationalTypeMappingSourcePlugin.cs index 05d8796df7c..4d8c7f25d00 100644 --- a/src/EFCore.Relational/Storage/IRelationalTypeMappingSourcePlugin.cs +++ b/src/EFCore.Relational/Storage/IRelationalTypeMappingSourcePlugin.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -23,6 +25,6 @@ public interface IRelationalTypeMappingSourcePlugin /// /// The mapping info to use to create the mapping. /// The type mapping, or if none could be found. - RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo); + RelationalTypeMapping? FindMapping(in RelationalTypeMappingInfo mappingInfo); } } diff --git a/src/EFCore.Relational/Storage/IRelationalValueBufferFactory.cs b/src/EFCore.Relational/Storage/IRelationalValueBufferFactory.cs index 3c75bb306e8..9751a707a47 100644 --- a/src/EFCore.Relational/Storage/IRelationalValueBufferFactory.cs +++ b/src/EFCore.Relational/Storage/IRelationalValueBufferFactory.cs @@ -4,6 +4,8 @@ using System.Data.Common; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/IRelationalValueBufferFactoryFactory.cs b/src/EFCore.Relational/Storage/IRelationalValueBufferFactoryFactory.cs index 62ba8d3d688..ce7a0f54b14 100644 --- a/src/EFCore.Relational/Storage/IRelationalValueBufferFactoryFactory.cs +++ b/src/EFCore.Relational/Storage/IRelationalValueBufferFactoryFactory.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/ISqlGenerationHelper.cs b/src/EFCore.Relational/Storage/ISqlGenerationHelper.cs index 5fd2b278641..53ac308415d 100644 --- a/src/EFCore.Relational/Storage/ISqlGenerationHelper.cs +++ b/src/EFCore.Relational/Storage/ISqlGenerationHelper.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -104,7 +106,7 @@ public interface ISqlGenerationHelper /// The identifier to delimit. /// The schema of the identifier. /// The generated string. - string DelimitIdentifier([NotNull] string name, [CanBeNull] string schema); + string DelimitIdentifier([NotNull] string name, [CanBeNull] string? schema); /// /// Writes the delimited SQL representation of an identifier (column name, table name, etc.). @@ -112,7 +114,7 @@ public interface ISqlGenerationHelper /// The to write generated string to. /// The identifier to delimit. /// The schema of the identifier. - void DelimitIdentifier([NotNull] StringBuilder builder, [NotNull] string name, [CanBeNull] string schema); + void DelimitIdentifier([NotNull] StringBuilder builder, [NotNull] string name, [CanBeNull] string? schema); /// /// Generates a SQL comment. diff --git a/src/EFCore.Relational/Storage/IntTypeMapping.cs b/src/EFCore.Relational/Storage/IntTypeMapping.cs index 06609da5e99..0532af4a3a4 100644 --- a/src/EFCore.Relational/Storage/IntTypeMapping.cs +++ b/src/EFCore.Relational/Storage/IntTypeMapping.cs @@ -4,6 +4,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/Internal/CompositeRelationalParameter.cs b/src/EFCore.Relational/Storage/Internal/CompositeRelationalParameter.cs index 6c58a445d1e..1d5f2bbef7e 100644 --- a/src/EFCore.Relational/Storage/Internal/CompositeRelationalParameter.cs +++ b/src/EFCore.Relational/Storage/Internal/CompositeRelationalParameter.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// @@ -27,23 +29,13 @@ public class CompositeRelationalParameter : RelationalParameterBase public CompositeRelationalParameter( [NotNull] string invariantName, [NotNull] IReadOnlyList relationalParameters) - + : base(invariantName) { - Check.NotNull(invariantName, nameof(invariantName)); Check.NotNull(relationalParameters, nameof(relationalParameters)); - InvariantName = invariantName; RelationalParameters = relationalParameters; } - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public override string InvariantName { get; } - /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -58,7 +50,7 @@ public CompositeRelationalParameter( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public override void AddDbParameter(DbCommand command, object value) + public override void AddDbParameter(DbCommand command, object? value) { Check.NotNull(command, nameof(command)); Check.NotNull(value, nameof(value)); diff --git a/src/EFCore.Relational/Storage/Internal/DbParameterCollectionExtensions.cs b/src/EFCore.Relational/Storage/Internal/DbParameterCollectionExtensions.cs index 1759cb4b46c..a0620411199 100644 --- a/src/EFCore.Relational/Storage/Internal/DbParameterCollectionExtensions.cs +++ b/src/EFCore.Relational/Storage/Internal/DbParameterCollectionExtensions.cs @@ -11,6 +11,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// @@ -60,7 +62,7 @@ public static string FormatParameter([NotNull] this DbParameter parameter, bool /// public static string FormatParameter( [NotNull] string name, - [CanBeNull] object value, + [CanBeNull] object? value, bool hasValue, ParameterDirection direction, DbType dbType, @@ -81,7 +83,7 @@ public static string FormatParameter( if (nullable && value != null - && !clrType.IsNullableType()) + && !clrType!.IsNullableType()) { builder.Append(" (Nullable = true)"); } @@ -90,7 +92,7 @@ public static string FormatParameter( if (!nullable && hasValue && (value == null - || clrType.IsNullableType())) + || clrType!.IsNullableType())) { builder.Append(" (Nullable = false)"); } @@ -139,7 +141,7 @@ public static string FormatParameter( return builder.ToString(); } - private static void FormatParameterValue(StringBuilder builder, object parameterValue) + private static void FormatParameterValue(StringBuilder builder, object? parameterValue) { if (parameterValue == null || parameterValue == DBNull.Value) @@ -172,7 +174,8 @@ private static void FormatParameterValue(StringBuilder builder, object parameter { var isNullProperty = parameterValue.GetType().GetRuntimeProperty("IsNull"); if (isNullProperty != null - && (bool)isNullProperty.GetValue(parameterValue)) + && isNullProperty.GetValue(parameterValue) is bool isNull + && isNull) { builder.Append("''"); } @@ -191,7 +194,7 @@ private static void FormatParameterValue(StringBuilder builder, object parameter } } - private static bool ShouldShowDbType(bool hasValue, DbType dbType, Type type) + private static bool ShouldShowDbType(bool hasValue, DbType dbType, Type? type) { if (!hasValue || type == null diff --git a/src/EFCore.Relational/Storage/Internal/DynamicRelationalParameter.cs b/src/EFCore.Relational/Storage/Internal/DynamicRelationalParameter.cs index 3333f33c24b..da4e4f52030 100644 --- a/src/EFCore.Relational/Storage/Internal/DynamicRelationalParameter.cs +++ b/src/EFCore.Relational/Storage/Internal/DynamicRelationalParameter.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// @@ -28,24 +30,15 @@ public DynamicRelationalParameter( [NotNull] string invariantName, [NotNull] string name, [NotNull] IRelationalTypeMappingSource typeMappingSource) + : base(invariantName) { - Check.NotEmpty(invariantName, nameof(invariantName)); Check.NotEmpty(name, nameof(name)); Check.NotNull(typeMappingSource, nameof(typeMappingSource)); - InvariantName = invariantName; Name = name; _typeMappingSource = typeMappingSource; } - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public override string InvariantName { get; } - /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -60,7 +53,7 @@ public DynamicRelationalParameter( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public override void AddDbParameter(DbCommand command, object value) + public override void AddDbParameter(DbCommand command, object? value) { Check.NotNull(command, nameof(command)); diff --git a/src/EFCore.Relational/Storage/Internal/INamedConnectionStringResolver.cs b/src/EFCore.Relational/Storage/Internal/INamedConnectionStringResolver.cs index e3acb7f21ac..c1608a01415 100644 --- a/src/EFCore.Relational/Storage/Internal/INamedConnectionStringResolver.cs +++ b/src/EFCore.Relational/Storage/Internal/INamedConnectionStringResolver.cs @@ -4,6 +4,8 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// diff --git a/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolver.cs b/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolver.cs index 01eaa307d12..40cb69b19a6 100644 --- a/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolver.cs +++ b/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolver.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// @@ -43,7 +45,7 @@ public NamedConnectionStringResolver([NotNull] IDbContextOptions options) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override IServiceProvider ApplicationServiceProvider + protected override IServiceProvider? ApplicationServiceProvider => _options.FindExtension() ?.ApplicationServiceProvider; } diff --git a/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolverBase.cs b/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolverBase.cs index bd3632376ca..bec409bef82 100644 --- a/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolverBase.cs +++ b/src/EFCore.Relational/Storage/Internal/NamedConnectionStringResolverBase.cs @@ -6,6 +6,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// @@ -32,7 +34,7 @@ public abstract class NamedConnectionStringResolverBase : INamedConnectionString /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected abstract IServiceProvider ApplicationServiceProvider { get; } + protected abstract IServiceProvider? ApplicationServiceProvider { get; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -64,7 +66,7 @@ public virtual string ResolveConnectionString(string connectionString) return resolved; } - private static string TryGetConnectionName(string connectionString) + private static string? TryGetConnectionName(string connectionString) { var firstEquals = connectionString.IndexOf('='); if (firstEquals < 0) diff --git a/src/EFCore.Relational/Storage/Internal/RawRelationalParameter.cs b/src/EFCore.Relational/Storage/Internal/RawRelationalParameter.cs index d10a141dba0..7be9b248659 100644 --- a/src/EFCore.Relational/Storage/Internal/RawRelationalParameter.cs +++ b/src/EFCore.Relational/Storage/Internal/RawRelationalParameter.cs @@ -8,6 +8,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// @@ -29,11 +31,10 @@ public class RawRelationalParameter : RelationalParameterBase public RawRelationalParameter( [NotNull] string invariantName, [NotNull] DbParameter parameter) + : base(invariantName) { - Check.NotEmpty(invariantName, nameof(invariantName)); Check.NotNull(parameter, nameof(parameter)); - InvariantName = invariantName; _parameter = parameter; } @@ -43,15 +44,7 @@ public RawRelationalParameter( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public override string InvariantName { get; } - - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public override void AddDbParameter(DbCommand command, IReadOnlyDictionary parameterValues) + public override void AddDbParameter(DbCommand command, IReadOnlyDictionary parameterValues) { AddDbParameter(command, _parameter); } @@ -62,8 +55,11 @@ public override void AddDbParameter(DbCommand command, IReadOnlyDictionary - public override void AddDbParameter(DbCommand command, object value) + public override void AddDbParameter(DbCommand command, object? value) { + Check.DebugAssert(value is DbParameter, + $"{nameof(value)} isn't a DbParameter in {nameof(RawRelationalParameter)}.{nameof(AddDbParameter)}"); + if (value is DbParameter dbParameter && dbParameter.Direction == ParameterDirection.Input && value is ICloneable cloneable) diff --git a/src/EFCore.Relational/Storage/Internal/RawSqlCommandBuilder.cs b/src/EFCore.Relational/Storage/Internal/RawSqlCommandBuilder.cs index ae10e02afe6..f2c42883072 100644 --- a/src/EFCore.Relational/Storage/Internal/RawSqlCommandBuilder.cs +++ b/src/EFCore.Relational/Storage/Internal/RawSqlCommandBuilder.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// @@ -74,7 +76,7 @@ public virtual RawSqlCommand Build(string sql, IEnumerable parameters) var parameterNameGenerator = _parameterNameGeneratorFactory.Create(); - var parameterValues = new Dictionary(); + var parameterValues = new Dictionary(); foreach (var parameter in parameters) { diff --git a/src/EFCore.Relational/Storage/Internal/RelationalDatabaseFacadeDependencies.cs b/src/EFCore.Relational/Storage/Internal/RelationalDatabaseFacadeDependencies.cs index e4d8c59f9d2..ef86f1159ac 100644 --- a/src/EFCore.Relational/Storage/Internal/RelationalDatabaseFacadeDependencies.cs +++ b/src/EFCore.Relational/Storage/Internal/RelationalDatabaseFacadeDependencies.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// diff --git a/src/EFCore.Relational/Storage/Internal/RelationalParameterBase.cs b/src/EFCore.Relational/Storage/Internal/RelationalParameterBase.cs index 3c46f70176e..49f2341a7dc 100644 --- a/src/EFCore.Relational/Storage/Internal/RelationalParameterBase.cs +++ b/src/EFCore.Relational/Storage/Internal/RelationalParameterBase.cs @@ -4,9 +4,12 @@ using System; using System.Collections.Generic; using System.Data.Common; +using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// @@ -17,6 +20,19 @@ namespace Microsoft.EntityFrameworkCore.Storage.Internal /// public abstract class RelationalParameterBase : IRelationalParameter { + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + protected RelationalParameterBase([NotNull] string invariantName) + { + Check.NotEmpty(invariantName, nameof(invariantName)); + + InvariantName = invariantName; + } + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -31,7 +47,7 @@ public abstract class RelationalParameterBase : IRelationalParameter /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public abstract void AddDbParameter(DbCommand command, object value); + public abstract void AddDbParameter(DbCommand command, object? value); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -39,7 +55,7 @@ public abstract class RelationalParameterBase : IRelationalParameter /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual void AddDbParameter(DbCommand command, IReadOnlyDictionary parameterValues) + public virtual void AddDbParameter(DbCommand command, IReadOnlyDictionary parameterValues) { Check.NotNull(command, nameof(command)); Check.NotNull(parameterValues, nameof(parameterValues)); diff --git a/src/EFCore.Relational/Storage/Internal/TypeMappedPropertyRelationalParameter.cs b/src/EFCore.Relational/Storage/Internal/TypeMappedPropertyRelationalParameter.cs index bfa23d41a60..a0850cb801a 100644 --- a/src/EFCore.Relational/Storage/Internal/TypeMappedPropertyRelationalParameter.cs +++ b/src/EFCore.Relational/Storage/Internal/TypeMappedPropertyRelationalParameter.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// @@ -42,7 +44,7 @@ public TypeMappedPropertyRelationalParameter( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public override void AddDbParameter(DbCommand command, object value) + public override void AddDbParameter(DbCommand command, object? value) { Check.DebugAssert(value != null, "value is null"); diff --git a/src/EFCore.Relational/Storage/Internal/TypeMappedRelationalParameter.cs b/src/EFCore.Relational/Storage/Internal/TypeMappedRelationalParameter.cs index c7fe4d6cc33..adf727e4df9 100644 --- a/src/EFCore.Relational/Storage/Internal/TypeMappedRelationalParameter.cs +++ b/src/EFCore.Relational/Storage/Internal/TypeMappedRelationalParameter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// @@ -26,25 +28,16 @@ public TypeMappedRelationalParameter( [NotNull] string name, [NotNull] RelationalTypeMapping relationalTypeMapping, bool? nullable) + : base(invariantName) { - Check.NotEmpty(invariantName, nameof(invariantName)); Check.NotEmpty(name, nameof(name)); Check.NotNull(relationalTypeMapping, nameof(relationalTypeMapping)); - InvariantName = invariantName; Name = name; RelationalTypeMapping = relationalTypeMapping; IsNullable = nullable; } - /// - /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to - /// the same compatibility standards as public APIs. It may be changed or removed without notice in - /// any release. You should only use it directly in your code with extreme caution and knowing that - /// doing so can result in application failures when updating to a new Entity Framework Core release. - /// - public override string InvariantName { get; } - /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -65,7 +58,7 @@ public TypeMappedRelationalParameter( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public override void AddDbParameter(DbCommand command, object value) + public override void AddDbParameter(DbCommand command, object? value) { Check.NotNull(command, nameof(command)); diff --git a/src/EFCore.Relational/Storage/Internal/TypedRelationalValueBufferFactory.cs b/src/EFCore.Relational/Storage/Internal/TypedRelationalValueBufferFactory.cs index f4aac279d0b..1ec65f22b02 100644 --- a/src/EFCore.Relational/Storage/Internal/TypedRelationalValueBufferFactory.cs +++ b/src/EFCore.Relational/Storage/Internal/TypedRelationalValueBufferFactory.cs @@ -7,6 +7,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// diff --git a/src/EFCore.Relational/Storage/LongTypeMapping.cs b/src/EFCore.Relational/Storage/LongTypeMapping.cs index 2cc36bfd88b..23bdd63c44d 100644 --- a/src/EFCore.Relational/Storage/LongTypeMapping.cs +++ b/src/EFCore.Relational/Storage/LongTypeMapping.cs @@ -4,6 +4,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/ParameterNameGenerator.cs b/src/EFCore.Relational/Storage/ParameterNameGenerator.cs index beb27e43f7e..d0160d6b02e 100644 --- a/src/EFCore.Relational/Storage/ParameterNameGenerator.cs +++ b/src/EFCore.Relational/Storage/ParameterNameGenerator.cs @@ -1,6 +1,8 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/ParameterNameGeneratorDependencies.cs b/src/EFCore.Relational/Storage/ParameterNameGeneratorDependencies.cs index 3615bc407a6..3fedc200b82 100644 --- a/src/EFCore.Relational/Storage/ParameterNameGeneratorDependencies.cs +++ b/src/EFCore.Relational/Storage/ParameterNameGeneratorDependencies.cs @@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/ParameterNameGeneratorFactory.cs b/src/EFCore.Relational/Storage/ParameterNameGeneratorFactory.cs index b369e5021f9..202ae17bef0 100644 --- a/src/EFCore.Relational/Storage/ParameterNameGeneratorFactory.cs +++ b/src/EFCore.Relational/Storage/ParameterNameGeneratorFactory.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RawSqlCommand.cs b/src/EFCore.Relational/Storage/RawSqlCommand.cs index 5d5d4c70cd5..e2f4e564869 100644 --- a/src/EFCore.Relational/Storage/RawSqlCommand.cs +++ b/src/EFCore.Relational/Storage/RawSqlCommand.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -25,7 +27,7 @@ public class RawSqlCommand /// The values to be assigned to parameters. public RawSqlCommand( [NotNull] IRelationalCommand relationalCommand, - [NotNull] IReadOnlyDictionary parameterValues) + [NotNull] IReadOnlyDictionary parameterValues) { Check.NotNull(relationalCommand, nameof(relationalCommand)); Check.NotNull(parameterValues, nameof(parameterValues)); @@ -42,6 +44,6 @@ public RawSqlCommand( /// /// Gets the values to be assigned to parameters. /// - public virtual IReadOnlyDictionary ParameterValues { get; } + public virtual IReadOnlyDictionary ParameterValues { get; } } } diff --git a/src/EFCore.Relational/Storage/ReaderColumn.cs b/src/EFCore.Relational/Storage/ReaderColumn.cs index 3847aadf80f..f22d6f6550a 100644 --- a/src/EFCore.Relational/Storage/ReaderColumn.cs +++ b/src/EFCore.Relational/Storage/ReaderColumn.cs @@ -8,6 +8,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -21,8 +23,7 @@ namespace Microsoft.EntityFrameworkCore.Storage /// public abstract class ReaderColumn { - private static readonly ConcurrentDictionary _constructors - = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary _constructors = new(); /// /// Creates a new instance of the class. @@ -31,7 +32,7 @@ private static readonly ConcurrentDictionary _constructor /// A value indicating if the column is nullable. /// The name of the column. [Obsolete("Use constructor which also takes IPropertyBase.")] - protected ReaderColumn([NotNull] Type type, bool nullable, [CanBeNull] string name) + protected ReaderColumn([NotNull] Type type, bool nullable, [CanBeNull] string? name) : this(type, nullable, name, null) { } @@ -43,7 +44,7 @@ protected ReaderColumn([NotNull] Type type, bool nullable, [CanBeNull] string na /// A value indicating if the column is nullable. /// The name of the column. /// The property being read if any, null otherwise. - protected ReaderColumn([NotNull] Type type, bool nullable, [CanBeNull] string name, [CanBeNull] IPropertyBase property) + protected ReaderColumn([NotNull] Type type, bool nullable, [CanBeNull] string? name, [CanBeNull] IPropertyBase? property) { Type = type; IsNullable = nullable; @@ -64,12 +65,12 @@ protected ReaderColumn([NotNull] Type type, bool nullable, [CanBeNull] string na /// /// The name of the column. /// - public virtual string Name { get; } + public virtual string? Name { get; } /// /// The property being read if any, null otherwise. /// - public virtual IPropertyBase Property { get; } + public virtual IPropertyBase? Property { get; } /// /// Creates an instance of . @@ -82,7 +83,7 @@ protected ReaderColumn([NotNull] Type type, bool nullable, [CanBeNull] string na /// /// An instance of . [Obsolete("Use method which also takes IPropertyBase.")] - public static ReaderColumn Create([NotNull] Type type, bool nullable, [CanBeNull] string columnName, [NotNull] object readFunc) + public static ReaderColumn Create([NotNull] Type type, bool nullable, [CanBeNull] string? columnName, [NotNull] object? readFunc) => (ReaderColumn)GetConstructor(type).Invoke(new[] { nullable, columnName, readFunc }); /// @@ -99,8 +100,8 @@ public static ReaderColumn Create([NotNull] Type type, bool nullable, [CanBeNull public static ReaderColumn Create( [NotNull] Type type, bool nullable, - [CanBeNull] string columnName, - [CanBeNull] IPropertyBase property, + [CanBeNull] string? columnName, + [CanBeNull] IPropertyBase? property, [NotNull] object readFunc) => (ReaderColumn)GetConstructor(type).Invoke(new[] { nullable, columnName, property, readFunc }); diff --git a/src/EFCore.Relational/Storage/ReaderColumn`.cs b/src/EFCore.Relational/Storage/ReaderColumn`.cs index e37ff7b767f..27ea21efa5b 100644 --- a/src/EFCore.Relational/Storage/ReaderColumn`.cs +++ b/src/EFCore.Relational/Storage/ReaderColumn`.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -26,7 +28,7 @@ public class ReaderColumn : ReaderColumn /// The name of the column. /// A function to get field value for the column from the reader. [Obsolete("Use constructor which also takes IPropertyBase.")] - public ReaderColumn(bool nullable, [CanBeNull] string name, [NotNull] Func getFieldValue) + public ReaderColumn(bool nullable, [CanBeNull] string? name, [NotNull] Func getFieldValue) : this(nullable, name, property: null, getFieldValue) { } @@ -40,8 +42,8 @@ public ReaderColumn(bool nullable, [CanBeNull] string name, [NotNull] Func A function to get field value for the column from the reader. public ReaderColumn( bool nullable, - [CanBeNull] string name, - [CanBeNull] IPropertyBase property, + [CanBeNull] string? name, + [CanBeNull] IPropertyBase? property, [NotNull] Func getFieldValue) : base(typeof(T), nullable, name, property) { diff --git a/src/EFCore.Relational/Storage/RelationalCommand.cs b/src/EFCore.Relational/Storage/RelationalCommand.cs index f9ee7f39c54..c69d4be0cab 100644 --- a/src/EFCore.Relational/Storage/RelationalCommand.cs +++ b/src/EFCore.Relational/Storage/RelationalCommand.cs @@ -12,6 +12,8 @@ using Microsoft.EntityFrameworkCore.Query.Internal; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -235,7 +237,7 @@ await logger.CommandErrorAsync( /// /// Parameters for this method. /// The result of the command. - public virtual object ExecuteScalar(RelationalCommandParameterObject parameterObject) + public virtual object? ExecuteScalar(RelationalCommandParameterObject parameterObject) { var (connection, context, logger) = (parameterObject.Connection, parameterObject.Context, parameterObject.Logger); @@ -302,7 +304,7 @@ public virtual object ExecuteScalar(RelationalCommandParameterObject parameterOb /// A task that represents the asynchronous operation. The task result contains the result of the command. /// /// If the is canceled. - public virtual async Task ExecuteScalarAsync( + public virtual async Task ExecuteScalarAsync( RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken = default) { @@ -637,8 +639,7 @@ public virtual DbCommand CreateDbCommand( command.CommandTimeout = (int)connection.CommandTimeout; } - if (Parameters != null - && Parameters.Count > 0) + if (Parameters.Count > 0) { var parameterValues = parameterObject.ParameterValues; if (parameterValues == null) @@ -680,7 +681,7 @@ protected virtual RelationalDataReader CreateRelationalDataReader( [NotNull] DbCommand command, [NotNull] DbDataReader reader, Guid commandId, - [CanBeNull] IDiagnosticsLogger logger) + [CanBeNull] IDiagnosticsLogger? logger) => new RelationalDataReader( connection, command, diff --git a/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs b/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs index 11a10d28b18..ac0c681d630 100644 --- a/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs +++ b/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalCommandBuilderDependencies.cs b/src/EFCore.Relational/Storage/RelationalCommandBuilderDependencies.cs index 8f8a716d7df..d892cb31fe7 100644 --- a/src/EFCore.Relational/Storage/RelationalCommandBuilderDependencies.cs +++ b/src/EFCore.Relational/Storage/RelationalCommandBuilderDependencies.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalCommandBuilderExtensions.cs b/src/EFCore.Relational/Storage/RelationalCommandBuilderExtensions.cs index 125a6939ecc..664c7da5a32 100644 --- a/src/EFCore.Relational/Storage/RelationalCommandBuilderExtensions.cs +++ b/src/EFCore.Relational/Storage/RelationalCommandBuilderExtensions.cs @@ -10,6 +10,8 @@ using Microsoft.EntityFrameworkCore.Storage.Internal; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -54,7 +56,7 @@ public static IRelationalCommandBuilder AppendLines( using (var reader = new StringReader(value)) { var first = true; - string line; + string? line; while ((line = reader.ReadLine()) != null) { if (first) diff --git a/src/EFCore.Relational/Storage/RelationalCommandBuilderFactory.cs b/src/EFCore.Relational/Storage/RelationalCommandBuilderFactory.cs index 5a4868b070d..0ebed6ec156 100644 --- a/src/EFCore.Relational/Storage/RelationalCommandBuilderFactory.cs +++ b/src/EFCore.Relational/Storage/RelationalCommandBuilderFactory.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalCommandParameterObject.cs b/src/EFCore.Relational/Storage/RelationalCommandParameterObject.cs index e0f996c89b7..1b87211ef44 100644 --- a/src/EFCore.Relational/Storage/RelationalCommandParameterObject.cs +++ b/src/EFCore.Relational/Storage/RelationalCommandParameterObject.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -35,10 +37,10 @@ public readonly struct RelationalCommandParameterObject /// A logger, or null if no logger is available. public RelationalCommandParameterObject( [NotNull] IRelationalConnection connection, - [CanBeNull] IReadOnlyDictionary parameterValues, - [CanBeNull] IReadOnlyList readerColumns, - [CanBeNull] DbContext context, - [CanBeNull] IDiagnosticsLogger logger) + [CanBeNull] IReadOnlyDictionary? parameterValues, + [CanBeNull] IReadOnlyList? readerColumns, + [CanBeNull] DbContext? context, + [CanBeNull] IDiagnosticsLogger? logger) : this(connection, parameterValues, readerColumns, context, logger, detailedErrorsEnabled: false) { } @@ -60,10 +62,10 @@ public RelationalCommandParameterObject( /// A value indicating if detailed errors are enabled. public RelationalCommandParameterObject( [NotNull] IRelationalConnection connection, - [CanBeNull] IReadOnlyDictionary parameterValues, - [CanBeNull] IReadOnlyList readerColumns, - [CanBeNull] DbContext context, - [CanBeNull] IDiagnosticsLogger logger, + [CanBeNull] IReadOnlyDictionary? parameterValues, + [CanBeNull] IReadOnlyList? readerColumns, + [CanBeNull] DbContext? context, + [CanBeNull] IDiagnosticsLogger? logger, bool detailedErrorsEnabled) { Check.NotNull(connection, nameof(connection)); @@ -84,22 +86,22 @@ public RelationalCommandParameterObject( /// /// The SQL parameter values to use, or null if none. /// - public IReadOnlyDictionary ParameterValues { get; } + public IReadOnlyDictionary? ParameterValues { get; } /// /// The expected columns if the reader needs to be buffered, or null otherwise. /// - public IReadOnlyList ReaderColumns { get; } + public IReadOnlyList? ReaderColumns { get; } /// /// The current instance, or null if it is not known. /// - public DbContext Context { get; } + public DbContext? Context { get; } /// /// A logger, or null if no logger is available. /// - public IDiagnosticsLogger Logger { get; } + public IDiagnosticsLogger? Logger { get; } /// /// A value indicating if detailed errors are enabled. diff --git a/src/EFCore.Relational/Storage/RelationalConnection.cs b/src/EFCore.Relational/Storage/RelationalConnection.cs index 4ef9dd52421..f039c768f98 100644 --- a/src/EFCore.Relational/Storage/RelationalConnection.cs +++ b/src/EFCore.Relational/Storage/RelationalConnection.cs @@ -16,6 +16,9 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; using IsolationLevel = System.Data.IsolationLevel; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable namespace Microsoft.EntityFrameworkCore.Storage { @@ -36,13 +39,13 @@ namespace Microsoft.EntityFrameworkCore.Storage /// public abstract class RelationalConnection : IRelationalConnection, ITransactionEnlistmentManager { - private string _connectionString; + private string? _connectionString; private bool _connectionOwned; private int _openedCount; private bool _openedInternally; private int? _commandTimeout; private readonly ConcurrentStack _ambientTransactions; - private DbConnection _connection; + private DbConnection? _connection; /// /// Initializes a new instance of the class. @@ -88,7 +91,7 @@ protected RelationalConnection([NotNull] RelationalConnectionDependencies depend public virtual Guid ConnectionId { get; } = Guid.NewGuid(); /// - /// The currently in use, or null if not known. + /// The currently in use. /// public virtual DbContext Context { get; } @@ -106,7 +109,7 @@ protected RelationalConnection([NotNull] RelationalConnectionDependencies depend /// /// Gets or sets the connection string for the database. /// - public virtual string ConnectionString + public virtual string? ConnectionString { get => _connectionString ?? _connection?.ConnectionString; set @@ -148,6 +151,7 @@ protected virtual string GetValidatedConnectionString() /// Note that a connection set must be disposed by application code since it was not created by Entity Framework. /// /// + [CA.AllowNull] public virtual DbConnection DbConnection { get @@ -181,12 +185,12 @@ public virtual DbConnection DbConnection /// /// Gets the current transaction. /// - public virtual IDbContextTransaction CurrentTransaction { get; [param: CanBeNull] protected set; } + public virtual IDbContextTransaction? CurrentTransaction { get; [param: CanBeNull] protected set; } /// /// The currently enlisted transaction. /// - public virtual Transaction EnlistedTransaction + public virtual Transaction? EnlistedTransaction { get { @@ -214,7 +218,7 @@ public virtual Transaction EnlistedTransaction /// Specifies an existing to be used for database operations. /// /// The transaction to be used. - public virtual void EnlistTransaction(Transaction transaction) + public virtual void EnlistTransaction(Transaction? transaction) { if (!SupportsAmbientTransactions) { @@ -237,7 +241,7 @@ public virtual void EnlistTransaction(Transaction transaction) /// by providers to make a different call instead. /// /// The transaction to be used. - protected virtual void ConnectionEnlistTransaction([NotNull] Transaction transaction) + protected virtual void ConnectionEnlistTransaction([CanBeNull] Transaction? transaction) => DbConnection.EnlistTransaction(transaction); /// @@ -268,8 +272,6 @@ public virtual int? CommandTimeout /// Begins a new transaction. /// /// The newly created transaction. - [NotNull] - // ReSharper disable once RedundantNameQualifier public virtual IDbContextTransaction BeginTransaction() => BeginTransaction(IsolationLevel.Unspecified); @@ -281,9 +283,7 @@ public virtual IDbContextTransaction BeginTransaction() /// A task that represents the asynchronous operation. The task result contains the newly created transaction. /// /// If the is canceled. - [NotNull] public virtual async Task BeginTransactionAsync(CancellationToken cancellationToken = default) - // ReSharper disable once RedundantNameQualifier => await BeginTransactionAsync(IsolationLevel.Unspecified, cancellationToken).ConfigureAwait(false); /// @@ -310,7 +310,7 @@ public virtual IDbContextTransaction BeginTransaction(IsolationLevel isolationLe var dbTransaction = interceptionResult.HasResult ? interceptionResult.Result - : ConnectionBeginTransation(isolationLevel); + : ConnectionBeginTransaction(isolationLevel); dbTransaction = Dependencies.TransactionLogger.TransactionStarted( this, @@ -328,7 +328,7 @@ public virtual IDbContextTransaction BeginTransaction(IsolationLevel isolationLe /// /// The isolation level to use for the transaction. /// The newly created transaction. - protected virtual DbTransaction ConnectionBeginTransation(IsolationLevel isolationLevel) + protected virtual DbTransaction ConnectionBeginTransaction(IsolationLevel isolationLevel) => DbConnection.BeginTransaction(isolationLevel); /// @@ -363,7 +363,7 @@ public virtual async Task BeginTransactionAsync( var dbTransaction = interceptionResult.HasResult ? interceptionResult.Result - : await ConnectionBeginTransationAsync(isolationLevel, cancellationToken).ConfigureAwait(false); + : await ConnectionBeginTransactionAsync(isolationLevel, cancellationToken).ConfigureAwait(false); dbTransaction = await Dependencies.TransactionLogger.TransactionStartedAsync( this, @@ -385,7 +385,7 @@ public virtual async Task BeginTransactionAsync( /// A to observe while waiting for the task to complete. /// The newly created transaction. /// If the is canceled. - protected virtual ValueTask ConnectionBeginTransationAsync( + protected virtual ValueTask ConnectionBeginTransactionAsync( IsolationLevel isolationLevel, CancellationToken cancellationToken = default) => DbConnection.BeginTransactionAsync(isolationLevel, cancellationToken); @@ -422,7 +422,7 @@ private IDbContextTransaction CreateRelationalTransaction(DbTransaction transact /// /// The transaction to be used. /// An instance of that wraps the provided transaction. - public virtual IDbContextTransaction UseTransaction(DbTransaction transaction) + public virtual IDbContextTransaction? UseTransaction(DbTransaction? transaction) => UseTransaction(transaction, Guid.NewGuid()); /// @@ -430,8 +430,12 @@ public virtual IDbContextTransaction UseTransaction(DbTransaction transaction) /// /// The transaction to be used. /// The unique identifier for the transaction. - /// An instance of that wraps the provided transaction. - public virtual IDbContextTransaction UseTransaction(DbTransaction transaction, Guid transactionId) + /// + /// An instance of that wraps the provided transaction, or + /// if is . + /// + [return: CA.NotNullIfNotNull("transaction")] + public virtual IDbContextTransaction? UseTransaction(DbTransaction? transaction, Guid transactionId) { if (ShouldUseTransaction(transaction)) { @@ -457,8 +461,8 @@ public virtual IDbContextTransaction UseTransaction(DbTransaction transaction, G /// A to observe while waiting for the task to complete. /// An instance of that wraps the provided transaction. /// If the is canceled. - public virtual Task UseTransactionAsync( - DbTransaction transaction, + public virtual Task UseTransactionAsync( + DbTransaction? transaction, CancellationToken cancellationToken = default) => UseTransactionAsync(transaction, Guid.NewGuid(), cancellationToken); @@ -470,8 +474,8 @@ public virtual Task UseTransactionAsync( /// A to observe while waiting for the task to complete. /// An instance of that wraps the provided transaction. /// If the is canceled. - public virtual async Task UseTransactionAsync( - DbTransaction transaction, + public virtual async Task UseTransactionAsync( + DbTransaction? transaction, Guid transactionId, CancellationToken cancellationToken = default) { @@ -494,7 +498,7 @@ public virtual async Task UseTransactionAsync( return CurrentTransaction; } - private bool ShouldUseTransaction(DbTransaction transaction) + private bool ShouldUseTransaction(DbTransaction? transaction) { if (transaction == null) { @@ -780,7 +784,7 @@ private void HandleAmbientTransactions() _ambientTransactions.Push(current); } - private void HandleTransactionCompleted(object sender, TransactionEventArgs e) + private void HandleTransactionCompleted(object? sender, TransactionEventArgs e) { // This could be invoked on a different thread at arbitrary time after the transaction completes _ambientTransactions.TryPeek(out var ambientTransaction); @@ -946,7 +950,7 @@ Task IResettableService.ResetStateAsync(CancellationToken cancellationToken) [Obsolete("EF Core no longer uses this semaphore. It will be removed in an upcoming release.")] public virtual SemaphoreSlim Semaphore { get; } = new SemaphoreSlim(1); - private Transaction _enlistedTransaction; + private Transaction? _enlistedTransaction; /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. diff --git a/src/EFCore.Relational/Storage/RelationalConnectionDependencies.cs b/src/EFCore.Relational/Storage/RelationalConnectionDependencies.cs index ddb7bb57954..0cae5aa2769 100644 --- a/src/EFCore.Relational/Storage/RelationalConnectionDependencies.cs +++ b/src/EFCore.Relational/Storage/RelationalConnectionDependencies.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalDataReader.cs b/src/EFCore.Relational/Storage/RelationalDataReader.cs index 58e438a7bbf..bc817ed42a2 100644 --- a/src/EFCore.Relational/Storage/RelationalDataReader.cs +++ b/src/EFCore.Relational/Storage/RelationalDataReader.cs @@ -10,6 +10,8 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -27,7 +29,7 @@ public class RelationalDataReader : IDisposable, IAsyncDisposable private readonly DbCommand _command; private readonly DbDataReader _reader; private readonly Guid _commandId; - private readonly IDiagnosticsLogger _logger; + private readonly IDiagnosticsLogger? _logger; private readonly DateTimeOffset _startTime; private readonly Stopwatch _stopwatch; @@ -48,7 +50,7 @@ public RelationalDataReader( [NotNull] DbCommand command, [NotNull] DbDataReader reader, Guid commandId, - [CanBeNull] IDiagnosticsLogger logger) + [CanBeNull] IDiagnosticsLogger? logger) { Check.NotNull(connection, nameof(connection)); Check.NotNull(command, nameof(command)); diff --git a/src/EFCore.Relational/Storage/RelationalDatabase.cs b/src/EFCore.Relational/Storage/RelationalDatabase.cs index a4308519cf7..1960a0ee553 100644 --- a/src/EFCore.Relational/Storage/RelationalDatabase.cs +++ b/src/EFCore.Relational/Storage/RelationalDatabase.cs @@ -10,6 +10,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs b/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs index 99ee26b0961..41d97aa1c93 100644 --- a/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs +++ b/src/EFCore.Relational/Storage/RelationalDatabaseCreator.cs @@ -12,6 +12,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalDatabaseCreatorDependencies.cs b/src/EFCore.Relational/Storage/RelationalDatabaseCreatorDependencies.cs index bbf69cd5f50..5922b871f9f 100644 --- a/src/EFCore.Relational/Storage/RelationalDatabaseCreatorDependencies.cs +++ b/src/EFCore.Relational/Storage/RelationalDatabaseCreatorDependencies.cs @@ -9,6 +9,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalDatabaseDependencies.cs b/src/EFCore.Relational/Storage/RelationalDatabaseDependencies.cs index e403a7c58b4..f849699784b 100644 --- a/src/EFCore.Relational/Storage/RelationalDatabaseDependencies.cs +++ b/src/EFCore.Relational/Storage/RelationalDatabaseDependencies.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalExecutionStrategyExtensions.cs b/src/EFCore.Relational/Storage/RelationalExecutionStrategyExtensions.cs index 0a62c8a2707..682a3d1face 100644 --- a/src/EFCore.Relational/Storage/RelationalExecutionStrategyExtensions.cs +++ b/src/EFCore.Relational/Storage/RelationalExecutionStrategyExtensions.cs @@ -7,6 +7,8 @@ using System.Threading.Tasks; using JetBrains.Annotations; +#nullable enable + // ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore.Storage { @@ -37,7 +39,7 @@ public static void ExecuteInTransaction( [NotNull] Action operation, [NotNull] Func verifySucceeded, IsolationLevel isolationLevel) - => strategy.ExecuteInTransaction(null, s => operation(), s => verifySucceeded(), isolationLevel); + => strategy.ExecuteInTransaction(null, s => operation(), s => verifySucceeded(), isolationLevel); /// /// Executes the specified asynchronous operation in a transaction. Allows to check whether @@ -65,7 +67,7 @@ public static Task ExecuteInTransactionAsync( [NotNull] Func operation, [NotNull] Func> verifySucceeded, IsolationLevel isolationLevel) - => strategy.ExecuteInTransactionAsync(null, (s, ct) => operation(), (s, ct) => verifySucceeded(), isolationLevel); + => strategy.ExecuteInTransactionAsync(null, (s, ct) => operation(), (s, ct) => verifySucceeded(), isolationLevel); /// /// Executes the specified asynchronous operation in a transaction. Allows to check whether @@ -99,7 +101,7 @@ public static Task ExecuteInTransactionAsync( [NotNull] Func> verifySucceeded, IsolationLevel isolationLevel, CancellationToken cancellationToken = default) - => strategy.ExecuteInTransactionAsync( + => strategy.ExecuteInTransactionAsync( null, (s, ct) => operation(ct), (s, ct) => verifySucceeded(ct), isolationLevel, cancellationToken); /// @@ -125,7 +127,7 @@ public static TResult ExecuteInTransaction( [NotNull] Func operation, [NotNull] Func verifySucceeded, IsolationLevel isolationLevel) - => strategy.ExecuteInTransaction(null, s => operation(), s => verifySucceeded(), isolationLevel); + => strategy.ExecuteInTransaction(null, s => operation(), s => verifySucceeded(), isolationLevel); /// /// Executes the specified asynchronous operation in a transaction and returns the result. Allows to check whether @@ -160,7 +162,7 @@ public static Task ExecuteInTransactionAsync( [NotNull] Func> verifySucceeded, IsolationLevel isolationLevel, CancellationToken cancellationToken = default) - => strategy.ExecuteInTransactionAsync( + => strategy.ExecuteInTransactionAsync( null, (s, ct) => operation(ct), (s, ct) => verifySucceeded(ct), isolationLevel, cancellationToken); /// diff --git a/src/EFCore.Relational/Storage/RelationalExecutionStrategyFactory.cs b/src/EFCore.Relational/Storage/RelationalExecutionStrategyFactory.cs index 808ced14382..9ec9f4ef727 100644 --- a/src/EFCore.Relational/Storage/RelationalExecutionStrategyFactory.cs +++ b/src/EFCore.Relational/Storage/RelationalExecutionStrategyFactory.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -35,9 +37,7 @@ public RelationalExecutionStrategyFactory([NotNull] ExecutionStrategyDependencie Dependencies = dependencies; - var configuredFactory = dependencies.Options == null - ? null - : RelationalOptionsExtension.Extract(dependencies.Options)?.ExecutionStrategyFactory; + var configuredFactory = RelationalOptionsExtension.Extract(dependencies.Options)?.ExecutionStrategyFactory; _createExecutionStrategy = configuredFactory ?? CreateDefaultStrategy; } diff --git a/src/EFCore.Relational/Storage/RelationalGeometryTypeMapping.cs b/src/EFCore.Relational/Storage/RelationalGeometryTypeMapping.cs index d1482473c26..487cf3e08fe 100644 --- a/src/EFCore.Relational/Storage/RelationalGeometryTypeMapping.cs +++ b/src/EFCore.Relational/Storage/RelationalGeometryTypeMapping.cs @@ -10,6 +10,9 @@ using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Microsoft.EntityFrameworkCore.Utilities; + +#nullable enable namespace Microsoft.EntityFrameworkCore.Storage { @@ -40,7 +43,7 @@ protected RelationalGeometryTypeMapping( /// The converter to use when converting to and from database types. protected RelationalGeometryTypeMapping( RelationalTypeMappingParameters parameters, - [CanBeNull] ValueConverter converter) + [CanBeNull] ValueConverter? converter) : base(parameters) { SpatialConverter = converter; @@ -49,7 +52,7 @@ protected RelationalGeometryTypeMapping( /// /// The underlying Geometry converter. /// - protected virtual ValueConverter SpatialConverter { get; } + protected virtual ValueConverter? SpatialConverter { get; } private static RelationalTypeMappingParameters CreateRelationalTypeMappingParameters(string storeType) { @@ -72,7 +75,7 @@ private static RelationalTypeMappingParameters CreateRelationalTypeMappingParame /// The value to be assigned to the parameter. /// A value indicating whether the parameter should be a nullable type. /// The newly created parameter. - public override DbParameter CreateParameter(DbCommand command, string name, object value, bool? nullable = null) + public override DbParameter CreateParameter(DbCommand command, string name, object? value, bool? nullable = null) { var parameter = command.CreateParameter(); parameter.Direction = ParameterDirection.Input; @@ -83,9 +86,11 @@ public override DbParameter CreateParameter(DbCommand command, string name, obje value = Converter.ConvertToProvider(value); } - parameter.Value = value == null + parameter.Value = value is null ? DBNull.Value - : SpatialConverter.ConvertToProvider(value); + : SpatialConverter is null + ? value + : SpatialConverter.ConvertToProvider(value); if (nullable.HasValue) { @@ -105,6 +110,11 @@ public override DbParameter CreateParameter(DbCommand command, string name, obje /// The expression with conversion added. public override Expression CustomizeDataReaderExpression(Expression expression) { + if (SpatialConverter is null) + { + return expression; + } + if (expression.Type != SpatialConverter.ProviderClrType) { expression = Expression.Convert(expression, SpatialConverter.ProviderClrType); @@ -127,7 +137,7 @@ public override Expression GenerateCodeLiteral(object value) => Expression.Convert( Expression.Call( Expression.New(WKTReaderType), - WKTReaderType.GetMethod("Read", new[] { typeof(string) }), + WKTReaderType.GetMethod("Read", new[] { typeof(string) })!, Expression.Constant(CreateWktWithSrid(value), typeof(string))), value.GetType()); diff --git a/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs b/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs index 1d525eba7dd..a40899d8aac 100644 --- a/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs +++ b/src/EFCore.Relational/Storage/RelationalSqlGenerationHelper.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -155,7 +157,7 @@ public virtual void DelimitIdentifier(StringBuilder builder, string identifier) /// /// The generated string. /// - public virtual string DelimitIdentifier(string name, string schema) + public virtual string DelimitIdentifier(string name, string? schema) => (!string.IsNullOrEmpty(schema) ? DelimitIdentifier(schema) + "." : string.Empty) @@ -167,7 +169,7 @@ public virtual string DelimitIdentifier(string name, string schema) /// The to write generated string to. /// The identifier to delimit. /// The schema of the identifier. - public virtual void DelimitIdentifier(StringBuilder builder, string name, string schema) + public virtual void DelimitIdentifier(StringBuilder builder, string name, string? schema) { if (!string.IsNullOrEmpty(schema)) { @@ -190,7 +192,7 @@ public virtual string GenerateComment(string text) var builder = new StringBuilder(); using (var reader = new StringReader(text)) { - string line; + string? line; while ((line = reader.ReadLine()) != null) { builder.Append(SingleLineCommentToken).Append(" ").AppendLine(line); diff --git a/src/EFCore.Relational/Storage/RelationalSqlGenerationHelperDependencies.cs b/src/EFCore.Relational/Storage/RelationalSqlGenerationHelperDependencies.cs index e2f3e51f33d..09300edda03 100644 --- a/src/EFCore.Relational/Storage/RelationalSqlGenerationHelperDependencies.cs +++ b/src/EFCore.Relational/Storage/RelationalSqlGenerationHelperDependencies.cs @@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalTransaction.cs b/src/EFCore.Relational/Storage/RelationalTransaction.cs index ad41391ab47..5e54d6e6749 100644 --- a/src/EFCore.Relational/Storage/RelationalTransaction.cs +++ b/src/EFCore.Relational/Storage/RelationalTransaction.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalTransactionFactory.cs b/src/EFCore.Relational/Storage/RelationalTransactionFactory.cs index d4438e2dbb4..4694d8c9b55 100644 --- a/src/EFCore.Relational/Storage/RelationalTransactionFactory.cs +++ b/src/EFCore.Relational/Storage/RelationalTransactionFactory.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalTransactionFactoryDependencies.cs b/src/EFCore.Relational/Storage/RelationalTransactionFactoryDependencies.cs index c48070bb52c..7240248a24c 100644 --- a/src/EFCore.Relational/Storage/RelationalTransactionFactoryDependencies.cs +++ b/src/EFCore.Relational/Storage/RelationalTransactionFactoryDependencies.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalTypeMapping.cs b/src/EFCore.Relational/Storage/RelationalTypeMapping.cs index 8a28b7820a3..d6d38c8589e 100644 --- a/src/EFCore.Relational/Storage/RelationalTypeMapping.cs +++ b/src/EFCore.Relational/Storage/RelationalTypeMapping.cs @@ -12,6 +12,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -248,7 +250,7 @@ private static readonly IDictionary _getXMethods }; private static MethodInfo GetDataReaderMethod(string name) - => typeof(DbDataReader).GetRuntimeMethod(name, new[] { typeof(int) }); + => typeof(DbDataReader).GetRuntimeMethod(name, new[] { typeof(int) })!; /// /// Gets the mapping to be used when the only piece of information is that there is a null value. @@ -276,16 +278,10 @@ protected RelationalTypeMapping(RelationalTypeMappingParameters parameters) Parameters = parameters; var storeType = parameters.StoreType; + var storeTypeNameBase = GetBaseName(storeType); - if (storeType != null) - { - var storeTypeNameBase = GetBaseName(storeType); - StoreTypeNameBase = storeTypeNameBase; - - storeType = ProcessStoreType(parameters, storeType, storeTypeNameBase); - } - - StoreType = storeType; + StoreTypeNameBase = storeTypeNameBase; + StoreType = ProcessStoreType(parameters, storeType, storeTypeNameBase); } /// @@ -482,7 +478,7 @@ public virtual bool IsFixedLength public virtual DbParameter CreateParameter( [NotNull] DbCommand command, [NotNull] string name, - [CanBeNull] object value, + [CanBeNull] object? value, bool? nullable = null) { Check.NotNull(command, nameof(command)); @@ -520,7 +516,7 @@ public virtual DbParameter CreateParameter( // when enum would contain convert node. We remove the convert node but we also // need to convert the integral value to enum value. // This allows us to use converter on enum value or print enum value directly if supported by provider - private object ConvertUnderlyingEnumValueToEnum(object value) + private object? ConvertUnderlyingEnumValueToEnum(object? value) => value?.GetType().IsInteger() == true && ClrType.UnwrapNullableType().IsEnum ? Enum.ToObject(ClrType.UnwrapNullableType(), value) : value; @@ -540,7 +536,7 @@ protected virtual void ConfigureParameter([NotNull] DbParameter parameter) /// /// The generated string. /// - public virtual string GenerateSqlLiteral([CanBeNull] object value) + public virtual string GenerateSqlLiteral([CanBeNull] object? value) { value = ConvertUnderlyingEnumValueToEnum(value); @@ -559,7 +555,7 @@ public virtual string GenerateSqlLiteral([CanBeNull] object value) /// /// The generated string. /// - public virtual string GenerateProviderValueSqlLiteral([CanBeNull] object value) + public virtual string GenerateProviderValueSqlLiteral([CanBeNull] object? value) => value == null ? "NULL" : GenerateNonNullSqlLiteral(value); diff --git a/src/EFCore.Relational/Storage/RelationalTypeMappingInfo.cs b/src/EFCore.Relational/Storage/RelationalTypeMappingInfo.cs index 9cbc92d253f..249485d9a15 100644 --- a/src/EFCore.Relational/Storage/RelationalTypeMappingInfo.cs +++ b/src/EFCore.Relational/Storage/RelationalTypeMappingInfo.cs @@ -9,6 +9,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -53,8 +55,8 @@ public RelationalTypeMappingInfo([NotNull] IProperty property) /// public RelationalTypeMappingInfo( [NotNull] IReadOnlyList principals, - [CanBeNull] string storeTypeName = null, - [CanBeNull] string storeTypeNameBase = null, + [CanBeNull] string? storeTypeName = null, + [CanBeNull] string? storeTypeNameBase = null, bool? fallbackUnicode = null, bool? fixedLength = null, int? fallbackSize = null, @@ -107,8 +109,8 @@ public RelationalTypeMappingInfo( /// Specifies a scale for the mapping, or for default. public RelationalTypeMappingInfo( [NotNull] MemberInfo member, - [CanBeNull] string storeTypeName = null, - [CanBeNull] string storeTypeNameBase = null, + [CanBeNull] string? storeTypeName = null, + [CanBeNull] string? storeTypeNameBase = null, bool? unicode = null, int? size = null, int? precision = null, @@ -162,8 +164,8 @@ public RelationalTypeMappingInfo( /// Specifies a scale for the mapping, or for default. public RelationalTypeMappingInfo( [NotNull] Type type, - [CanBeNull] string storeTypeName = null, - [CanBeNull] string storeTypeNameBase = null, + [CanBeNull] string? storeTypeName = null, + [CanBeNull] string? storeTypeNameBase = null, bool keyOrIndex = false, bool? unicode = null, int? size = null, @@ -182,12 +184,12 @@ public RelationalTypeMappingInfo( /// /// The provider-specific relational type name for which mapping is needed. /// - public string StoreTypeName { get; } + public string? StoreTypeName { get; } /// /// The provider-specific relational type name, with any facets removed. /// - public string StoreTypeNameBase { get; } + public string? StoreTypeNameBase { get; } /// /// Indicates the store-size to use for the mapping, or null if none. @@ -233,7 +235,7 @@ public bool? IsRowVersion /// /// The CLR type in the model. /// - public Type ClrType + public Type? ClrType => _coreTypeMappingInfo.ClrType; /// @@ -259,7 +261,7 @@ public bool Equals(RelationalTypeMappingInfo other) /// /// The other object. /// if they represent the same mapping; otherwise. - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj != null && obj.GetType() == GetType() && Equals((RelationalTypeMappingInfo)obj); diff --git a/src/EFCore.Relational/Storage/RelationalTypeMappingSource.cs b/src/EFCore.Relational/Storage/RelationalTypeMappingSource.cs index 41ad0e17c3f..409107e5533 100644 --- a/src/EFCore.Relational/Storage/RelationalTypeMappingSource.cs +++ b/src/EFCore.Relational/Storage/RelationalTypeMappingSource.cs @@ -12,6 +12,9 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +using CA = System.Diagnostics.CodeAnalysis; + +#nullable enable #pragma warning disable 1574, CS0419 // Ambiguous reference in cref attribute namespace Microsoft.EntityFrameworkCore.Storage @@ -33,8 +36,8 @@ namespace Microsoft.EntityFrameworkCore.Storage /// public abstract class RelationalTypeMappingSource : TypeMappingSourceBase, IRelationalTypeMappingSource { - private readonly ConcurrentDictionary<(RelationalTypeMappingInfo, Type, ValueConverter), RelationalTypeMapping> _explicitMappings - = new ConcurrentDictionary<(RelationalTypeMappingInfo, Type, ValueConverter), RelationalTypeMapping>(); + private readonly ConcurrentDictionary<(RelationalTypeMappingInfo, Type?, ValueConverter?), RelationalTypeMapping?> _explicitMappings + = new ConcurrentDictionary<(RelationalTypeMappingInfo, Type?, ValueConverter?), RelationalTypeMapping?>(); /// /// Initializes a new instance of the this class. @@ -63,7 +66,7 @@ protected RelationalTypeMappingSource( /// /// The mapping info to use to create the mapping. /// The type mapping, or if none could be found. - protected virtual RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo) + protected virtual RelationalTypeMapping? FindMapping(in RelationalTypeMappingInfo mappingInfo) { foreach (var plugin in RelationalDependencies.Plugins) { @@ -91,12 +94,12 @@ protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo) => throw new InvalidOperationException( RelationalStrings.NoneRelationalTypeMappingOnARelationalTypeMappingSource); - private RelationalTypeMapping FindMappingWithConversion( + private RelationalTypeMapping? FindMappingWithConversion( in RelationalTypeMappingInfo mappingInfo, - [CanBeNull] IReadOnlyList principals) + [CanBeNull] IReadOnlyList? principals) { - Type providerClrType = null; - ValueConverter customConverter = null; + Type? providerClrType = null; + ValueConverter? customConverter = null; if (principals != null) { for (var i = 0; i < principals.Count; i++) @@ -195,7 +198,7 @@ private RelationalTypeMapping FindMappingWithConversion( /// /// The property. /// The type mapping, or if none was found. - public override CoreTypeMapping FindMapping(IProperty property) + public override CoreTypeMapping? FindMapping(IProperty property) { var mapping = property.FindRelationalTypeMapping(); if (mapping != null) @@ -205,7 +208,7 @@ public override CoreTypeMapping FindMapping(IProperty property) var principals = property.FindPrincipals(); - string storeTypeName = null; + string? storeTypeName = null; bool? isFixedLength = null; // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < principals.Count; i++) @@ -213,7 +216,7 @@ public override CoreTypeMapping FindMapping(IProperty property) var principal = principals[i]; if (storeTypeName == null) { - var columnType = (string)principal[RelationalAnnotationNames.ColumnType]; + var columnType = (string?)principal[RelationalAnnotationNames.ColumnType]; if (columnType != null) { storeTypeName = columnType; @@ -248,7 +251,7 @@ public override CoreTypeMapping FindMapping(IProperty property) /// /// The CLR type. /// The type mapping, or if none was found. - public override CoreTypeMapping FindMapping(Type type) + public override CoreTypeMapping? FindMapping(Type type) => FindMappingWithConversion(new RelationalTypeMappingInfo(type), null); /// @@ -266,7 +269,7 @@ public override CoreTypeMapping FindMapping(Type type) /// /// The field or property. /// The type mapping, or if none was found. - public override CoreTypeMapping FindMapping(MemberInfo member) + public override CoreTypeMapping? FindMapping(MemberInfo member) { if (member.GetCustomAttribute(true) is ColumnAttribute attribute) { @@ -295,7 +298,7 @@ public override CoreTypeMapping FindMapping(MemberInfo member) /// /// The database type name. /// The type mapping, or if none was found. - public virtual RelationalTypeMapping FindMapping(string storeTypeName) + public virtual RelationalTypeMapping? FindMapping(string storeTypeName) { var storeTypeBaseName = ParseStoreTypeName(storeTypeName, out var unicode, out var size, out var precision, out var scale); @@ -325,9 +328,9 @@ public virtual RelationalTypeMapping FindMapping(string storeTypeName) /// Specifies a precision for the mapping, or for default. /// Specifies a scale for the mapping, or for default. /// The type mapping, or if none was found. - public virtual RelationalTypeMapping FindMapping( + public virtual RelationalTypeMapping? FindMapping( Type type, - string storeTypeName, + string? storeTypeName, bool keyOrIndex = false, bool? unicode = null, int? size = null, @@ -336,7 +339,7 @@ public virtual RelationalTypeMapping FindMapping( int? precision = null, int? scale = null) { - string storeTypeBaseName = null; + string? storeTypeBaseName = null; if (storeTypeName != null) { @@ -369,16 +372,16 @@ public virtual RelationalTypeMapping FindMapping( } /// - RelationalTypeMapping IRelationalTypeMappingSource.FindMapping(IProperty property) - => (RelationalTypeMapping)FindMapping(property); + RelationalTypeMapping? IRelationalTypeMappingSource.FindMapping(IProperty property) + => (RelationalTypeMapping?)FindMapping(property); /// - RelationalTypeMapping IRelationalTypeMappingSource.FindMapping(Type type) - => (RelationalTypeMapping)FindMapping(type); + RelationalTypeMapping? IRelationalTypeMappingSource.FindMapping(Type type) + => (RelationalTypeMapping?)FindMapping(type); /// - RelationalTypeMapping IRelationalTypeMappingSource.FindMapping(MemberInfo member) - => (RelationalTypeMapping)FindMapping(member); + RelationalTypeMapping? IRelationalTypeMappingSource.FindMapping(MemberInfo member) + => (RelationalTypeMapping?)FindMapping(member); /// /// @@ -397,8 +400,9 @@ RelationalTypeMapping IRelationalTypeMappingSource.FindMapping(MemberInfo member /// The precision parsed from the type name, or if none was specified. /// The scale parsed from the type name, or if none was specified. /// The provider-specific relational type name, with any facets removed. - protected virtual string ParseStoreTypeName( - [CanBeNull] string storeTypeName, + [return: CA.NotNullIfNotNull("storeTypeName")] + protected virtual string? ParseStoreTypeName( + [CanBeNull] string? storeTypeName, out bool? unicode, out int? size, out int? precision, diff --git a/src/EFCore.Relational/Storage/RelationalTypeMappingSourceDependencies.cs b/src/EFCore.Relational/Storage/RelationalTypeMappingSourceDependencies.cs index eeb52f7e11c..19054045f11 100644 --- a/src/EFCore.Relational/Storage/RelationalTypeMappingSourceDependencies.cs +++ b/src/EFCore.Relational/Storage/RelationalTypeMappingSourceDependencies.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/RelationalTypeMappingSourceExtensions.cs b/src/EFCore.Relational/Storage/RelationalTypeMappingSourceExtensions.cs index 84be3d31c19..f0539dc5eeb 100644 --- a/src/EFCore.Relational/Storage/RelationalTypeMappingSourceExtensions.cs +++ b/src/EFCore.Relational/Storage/RelationalTypeMappingSourceExtensions.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -22,8 +24,8 @@ public static class RelationalTypeMappingSourceExtensions /// The object to get the mapping for. /// The type mapping to be used. public static RelationalTypeMapping GetMappingForValue( - [CanBeNull] this IRelationalTypeMappingSource typeMappingSource, - [CanBeNull] object value) + [CanBeNull] this IRelationalTypeMappingSource? typeMappingSource, + [CanBeNull] object? value) => value == null || value == DBNull.Value || typeMappingSource == null diff --git a/src/EFCore.Relational/Storage/RelationalValueBufferFactoryDependencies.cs b/src/EFCore.Relational/Storage/RelationalValueBufferFactoryDependencies.cs index cf5eeb522dd..0bdaa8062b2 100644 --- a/src/EFCore.Relational/Storage/RelationalValueBufferFactoryDependencies.cs +++ b/src/EFCore.Relational/Storage/RelationalValueBufferFactoryDependencies.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/SByteTypeMapping.cs b/src/EFCore.Relational/Storage/SByteTypeMapping.cs index 5b4bf4fe1a4..724cdc86172 100644 --- a/src/EFCore.Relational/Storage/SByteTypeMapping.cs +++ b/src/EFCore.Relational/Storage/SByteTypeMapping.cs @@ -4,6 +4,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/ShortTypeMapping.cs b/src/EFCore.Relational/Storage/ShortTypeMapping.cs index 407fbb98833..a76d80bd2b3 100644 --- a/src/EFCore.Relational/Storage/ShortTypeMapping.cs +++ b/src/EFCore.Relational/Storage/ShortTypeMapping.cs @@ -4,6 +4,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/StoreTypePostfix.cs b/src/EFCore.Relational/Storage/StoreTypePostfix.cs index af2df2e059a..b4a7d8a191f 100644 --- a/src/EFCore.Relational/Storage/StoreTypePostfix.cs +++ b/src/EFCore.Relational/Storage/StoreTypePostfix.cs @@ -1,6 +1,8 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/StringTypeMapping.cs b/src/EFCore.Relational/Storage/StringTypeMapping.cs index 5410a6988cf..420b57e249b 100644 --- a/src/EFCore.Relational/Storage/StringTypeMapping.cs +++ b/src/EFCore.Relational/Storage/StringTypeMapping.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/TimeSpanTypeMapping.cs b/src/EFCore.Relational/Storage/TimeSpanTypeMapping.cs index 1ab2c569c8b..48ebebd86e3 100644 --- a/src/EFCore.Relational/Storage/TimeSpanTypeMapping.cs +++ b/src/EFCore.Relational/Storage/TimeSpanTypeMapping.cs @@ -5,6 +5,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/TypeMaterializationInfo.cs b/src/EFCore.Relational/Storage/TypeMaterializationInfo.cs index 72c99df177f..802397d17c3 100644 --- a/src/EFCore.Relational/Storage/TypeMaterializationInfo.cs +++ b/src/EFCore.Relational/Storage/TypeMaterializationInfo.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -14,48 +16,6 @@ namespace Microsoft.EntityFrameworkCore.Storage /// public class TypeMaterializationInfo { - /// - /// Creates a new instance. - /// - /// The type that is needed in the model after conversion. - /// The property associated with the type, or if none. - /// The type mapping source to use to find a mapping if the property does not have one already bound. - /// - /// The index of the underlying result set that should be used for this type, - /// or -1 if no index mapping is needed. - /// - [Obsolete] - public TypeMaterializationInfo( - [NotNull] Type modelClrType, - [CanBeNull] IProperty property, - [CanBeNull] IRelationalTypeMappingSource typeMappingSource, - int index = -1) - : this(modelClrType, property, typeMappingSource, null, index) - { - } - - /// - /// Creates a new instance. - /// - /// The type that is needed in the model after conversion. - /// The property associated with the type, or if none. - /// The type mapping source to use to find a mapping if the property does not have one already bound. - /// Whether or not the value is coming from a LEFT OUTER JOIN operation. - /// - /// The index of the underlying result set that should be used for this type, - /// or -1 if no index mapping is needed. - /// - [Obsolete] - public TypeMaterializationInfo( - [NotNull] Type modelClrType, - [CanBeNull] IProperty property, - [CanBeNull] IRelationalTypeMappingSource typeMappingSource, - bool? fromLeftOuterJoin, - int index) - : this(modelClrType, property, typeMappingSource, fromLeftOuterJoin, index, mapping: null) - { - } - /// /// Creates a new instance. /// @@ -65,60 +25,19 @@ public TypeMaterializationInfo( /// A value indicating whether the value could be null. public TypeMaterializationInfo( [NotNull] Type modelClrType, - [CanBeNull] IProperty property, + [CanBeNull] IProperty? property, [NotNull] RelationalTypeMapping mapping, bool? nullable = null) { Check.NotNull(modelClrType, nameof(modelClrType)); - ProviderClrType = mapping?.Converter?.ProviderClrType - ?? modelClrType; - + ProviderClrType = mapping.Converter?.ProviderClrType ?? modelClrType; ModelClrType = modelClrType; Mapping = mapping; Property = property; IsNullable = nullable; } - /// - /// Creates a new instance. - /// - /// The type that is needed in the model after conversion. - /// The property associated with the type, or if none. - /// The type mapping source to use to find a mapping if the property does not have one already bound. - /// Whether or not the value is coming from a LEFT OUTER JOIN operation. - /// - /// The index of the underlying result set that should be used for this type, - /// or -1 if no index mapping is needed. - /// - /// The type mapping to use or to infer one. - [Obsolete] - public TypeMaterializationInfo( - [NotNull] Type modelClrType, - [CanBeNull] IProperty property, - [CanBeNull] IRelationalTypeMappingSource typeMappingSource, - bool? fromLeftOuterJoin, - int index = -1, - [CanBeNull] RelationalTypeMapping mapping = null) - { - Check.NotNull(modelClrType, nameof(modelClrType)); - - if (mapping == null) - { - mapping = property?.GetRelationalTypeMapping() - ?? typeMappingSource?.GetMapping(modelClrType); - } - - ProviderClrType = mapping?.Converter?.ProviderClrType - ?? modelClrType; - - ModelClrType = modelClrType; - Mapping = mapping; - Property = property; - Index = index; - IsFromLeftOuterJoin = fromLeftOuterJoin; - } - /// /// The type that will be read from the database provider. /// @@ -137,7 +56,7 @@ public TypeMaterializationInfo( /// /// The property associated with the type, or if none. /// - public virtual IProperty Property { get; } + public virtual IProperty? Property { get; } /// /// The index of the underlying result set that should be used for this type, @@ -178,7 +97,7 @@ protected virtual bool Equals([NotNull] TypeMaterializationInfo other) /// /// The object to compare with the current object. /// if the specified object is equal to the current object; otherwise, . - public override bool Equals(object obj) + public override bool Equals(object? obj) => !(obj is null) && (ReferenceEquals(this, obj) || obj.GetType() == GetType() diff --git a/src/EFCore.Relational/Storage/TypedRelationalValueBufferFactoryFactory.cs b/src/EFCore.Relational/Storage/TypedRelationalValueBufferFactoryFactory.cs index 8b7d18aecf4..466a849f105 100644 --- a/src/EFCore.Relational/Storage/TypedRelationalValueBufferFactoryFactory.cs +++ b/src/EFCore.Relational/Storage/TypedRelationalValueBufferFactoryFactory.cs @@ -17,6 +17,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -48,13 +50,13 @@ public static readonly ParameterExpression DataReaderParameter = Expression.Parameter(typeof(DbDataReader), "dataReader"); private static readonly MethodInfo _getFieldValueMethod = - typeof(DbDataReader).GetRuntimeMethod(nameof(DbDataReader.GetFieldValue), new[] { typeof(int) }); + typeof(DbDataReader).GetRuntimeMethod(nameof(DbDataReader.GetFieldValue), new[] { typeof(int) })!; private static readonly MethodInfo _isDbNullMethod = - typeof(DbDataReader).GetRuntimeMethod(nameof(DbDataReader.IsDBNull), new[] { typeof(int) }); + typeof(DbDataReader).GetRuntimeMethod(nameof(DbDataReader.IsDBNull), new[] { typeof(int) })!; private static readonly MethodInfo _throwReadValueExceptionMethod - = typeof(TypedRelationalValueBufferFactoryFactory).GetTypeInfo().GetDeclaredMethod(nameof(ThrowReadValueException)); + = typeof(TypedRelationalValueBufferFactoryFactory).GetTypeInfo().GetDeclaredMethod(nameof(ThrowReadValueException))!; /// /// Initializes a new instance of the class. @@ -79,7 +81,7 @@ public CacheKey(IReadOnlyList materializationInfo) public IReadOnlyList TypeMaterializationInfo { get; } - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj is CacheKey cacheKey && Equals(cacheKey); public bool Equals(CacheKey other) @@ -98,8 +100,7 @@ public override int GetHashCode() } } - private readonly ConcurrentDictionary _cache - = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _cache = new(); /// /// Creates a new . @@ -152,8 +153,8 @@ private static Func CreateArrayInitializer(CacheKey cach [MethodImpl(MethodImplOptions.AggressiveInlining)] private static TValue ThrowReadValueException( Exception exception, - object value, - IPropertyBase property = null) + object? value, + IPropertyBase? property = null) { var expectedType = typeof(TValue); var actualType = value?.GetType(); @@ -204,7 +205,7 @@ private static Expression CreateGetValueExpression( Expression valueExpression = Expression.Call( getMethod.DeclaringType != typeof(DbDataReader) - ? Expression.Convert(dataReaderExpression, getMethod.DeclaringType) + ? Expression.Convert(dataReaderExpression, getMethod.DeclaringType!) : dataReaderExpression, getMethod, indexExpression); @@ -261,7 +262,7 @@ var catchBlock } #pragma warning disable CS0612 // Type or member is obsolete - if (materializationInfo?.IsNullable != false + if (materializationInfo.IsNullable != false || materializationInfo.IsFromLeftOuterJoin != false) { #pragma warning restore CS0612 // Type or member is obsolete diff --git a/src/EFCore.Relational/Storage/UIntTypeMapping.cs b/src/EFCore.Relational/Storage/UIntTypeMapping.cs index 4a9239b74cc..ce68fe492ab 100644 --- a/src/EFCore.Relational/Storage/UIntTypeMapping.cs +++ b/src/EFCore.Relational/Storage/UIntTypeMapping.cs @@ -4,6 +4,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/ULongTypeMapping.cs b/src/EFCore.Relational/Storage/ULongTypeMapping.cs index 10ec2197226..9fbcaf02eb2 100644 --- a/src/EFCore.Relational/Storage/ULongTypeMapping.cs +++ b/src/EFCore.Relational/Storage/ULongTypeMapping.cs @@ -4,6 +4,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/UShortTypeMapping.cs b/src/EFCore.Relational/Storage/UShortTypeMapping.cs index 63e17c72a77..a7bfdd391a8 100644 --- a/src/EFCore.Relational/Storage/UShortTypeMapping.cs +++ b/src/EFCore.Relational/Storage/UShortTypeMapping.cs @@ -4,6 +4,8 @@ using System.Data; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore.Relational/Storage/ValueConversion/RelationalConverterMappingHints.cs b/src/EFCore.Relational/Storage/ValueConversion/RelationalConverterMappingHints.cs index 4dde45ed7ba..00504979ef9 100644 --- a/src/EFCore.Relational/Storage/ValueConversion/RelationalConverterMappingHints.cs +++ b/src/EFCore.Relational/Storage/ValueConversion/RelationalConverterMappingHints.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.ValueGeneration; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -29,7 +31,7 @@ public RelationalConverterMappingHints( int? scale = null, bool? unicode = null, bool? fixedLength = null, - [CanBeNull] Func valueGeneratorFactory = null) + [CanBeNull] Func? valueGeneratorFactory = null) : base(size, precision, scale, unicode, valueGeneratorFactory) { IsFixedLength = fixedLength; @@ -41,7 +43,7 @@ public RelationalConverterMappingHints( /// /// The hints to add. /// The combined hints. - public override ConverterMappingHints With(ConverterMappingHints hints) + public override ConverterMappingHints With(ConverterMappingHints? hints) => hints == null ? this : new RelationalConverterMappingHints( diff --git a/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerGeometryTypeMapping.cs b/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerGeometryTypeMapping.cs index 4a07e76de1d..a4232ae4beb 100644 --- a/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerGeometryTypeMapping.cs +++ b/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerGeometryTypeMapping.cs @@ -18,6 +18,8 @@ using NetTopologySuite.Geometries; using NetTopologySuite.IO; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// @@ -30,10 +32,10 @@ public class SqlServerGeometryTypeMapping : RelationalGeometryTypeMap where TGeometry : Geometry { private static readonly MethodInfo _getSqlBytes - = typeof(SqlDataReader).GetRuntimeMethod(nameof(SqlDataReader.GetSqlBytes), new[] { typeof(int) }); + = typeof(SqlDataReader).GetRuntimeMethod(nameof(SqlDataReader.GetSqlBytes), new[] { typeof(int) })!; - private static Action _sqlDbTypeSetter; - private static Action _udtTypeNameSetter; + private static Action? _sqlDbTypeSetter; + private static Action? _udtTypeNameSetter; private readonly bool _isGeography; @@ -60,7 +62,7 @@ public SqlServerGeometryTypeMapping([NotNull] NtsGeometryServices geometryServic /// protected SqlServerGeometryTypeMapping( RelationalTypeMappingParameters parameters, - [CanBeNull] ValueConverter converter) + [CanBeNull] ValueConverter? converter) : base(parameters, converter) { _isGeography = IsGeography(StoreType); @@ -185,7 +187,7 @@ private static Action CreateSqlDbTypeAccessor(Type param return Expression.Lambda>( Expression.Call( Expression.Convert(paramParam, paramType), - paramType.GetProperty("SqlDbType").SetMethod, + paramType.GetProperty("SqlDbType")!.SetMethod!, valueParam), paramParam, valueParam).Compile(); @@ -199,7 +201,7 @@ private static Action CreateUdtTypeNameAccessor(Type paramT return Expression.Lambda>( Expression.Call( Expression.Convert(paramParam, paramType), - paramType.GetProperty("UdtTypeName").SetMethod, + paramType.GetProperty("UdtTypeName")!.SetMethod!, valueParam), paramParam, valueParam).Compile(); diff --git a/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerNetTopologySuiteTypeMappingSourcePlugin.cs b/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerNetTopologySuiteTypeMappingSourcePlugin.cs index 99b3b784810..982b70e978d 100644 --- a/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerNetTopologySuiteTypeMappingSourcePlugin.cs +++ b/src/EFCore.SqlServer.NTS/Storage/Internal/SqlServerNetTopologySuiteTypeMappingSourcePlugin.cs @@ -10,6 +10,8 @@ using NetTopologySuite; using NetTopologySuite.Geometries; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// @@ -28,7 +30,7 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal /// public class SqlServerNetTopologySuiteTypeMappingSourcePlugin : IRelationalTypeMappingSourcePlugin { - private readonly HashSet _spatialStoreTypes = new HashSet(StringComparer.OrdinalIgnoreCase) + private readonly HashSet _spatialStoreTypes = new(StringComparer.OrdinalIgnoreCase) { "geometry", "geography" }; @@ -54,7 +56,7 @@ public SqlServerNetTopologySuiteTypeMappingSourcePlugin([NotNull] NtsGeometrySer /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo) + public virtual RelationalTypeMapping? FindMapping(in RelationalTypeMappingInfo mappingInfo) { var clrType = mappingInfo.ClrType; var storeTypeName = mappingInfo.StoreTypeName; @@ -65,7 +67,7 @@ public virtual RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo ma ? (RelationalTypeMapping)Activator.CreateInstance( typeof(SqlServerGeometryTypeMapping<>).MakeGenericType(clrType ?? typeof(Geometry)), _geometryServices, - storeTypeName ?? "geography") + storeTypeName ?? "geography")! : null; } } diff --git a/src/EFCore.SqlServer/SqlServerRetryingExecutionStrategy.cs b/src/EFCore.SqlServer/SqlServerRetryingExecutionStrategy.cs index 161eddd64b6..e823b5b6c9e 100644 --- a/src/EFCore.SqlServer/SqlServerRetryingExecutionStrategy.cs +++ b/src/EFCore.SqlServer/SqlServerRetryingExecutionStrategy.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + // ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore { @@ -22,7 +24,7 @@ namespace Microsoft.EntityFrameworkCore /// public class SqlServerRetryingExecutionStrategy : ExecutionStrategy { - private readonly ICollection _additionalErrorNumbers; + private readonly ICollection? _additionalErrorNumbers; /// /// @@ -99,7 +101,7 @@ public SqlServerRetryingExecutionStrategy( [NotNull] DbContext context, int maxRetryCount, TimeSpan maxRetryDelay, - [CanBeNull] ICollection errorNumbersToAdd) + [CanBeNull] ICollection? errorNumbersToAdd) : base( context, maxRetryCount, @@ -117,7 +119,7 @@ public SqlServerRetryingExecutionStrategy( [NotNull] ExecutionStrategyDependencies dependencies, int maxRetryCount, TimeSpan maxRetryDelay, - [CanBeNull] ICollection errorNumbersToAdd) + [CanBeNull] ICollection? errorNumbersToAdd) : base(dependencies, maxRetryCount, maxRetryDelay) => _additionalErrorNumbers = errorNumbersToAdd; @@ -129,7 +131,7 @@ public SqlServerRetryingExecutionStrategy( /// /// if the specified exception is considered as transient, otherwise . /// - protected override bool ShouldRetryOn(Exception exception) + protected override bool ShouldRetryOn(Exception? exception) { if (_additionalErrorNumbers != null && exception is SqlException sqlException) @@ -167,7 +169,7 @@ protected override bool ShouldRetryOn(Exception exception) : baseDelay; } - private static bool IsMemoryOptimizedError(Exception exception) + private static bool IsMemoryOptimizedError(Exception? exception) { if (exception is SqlException sqlException) { diff --git a/src/EFCore.SqlServer/Storage/Internal/ISqlServerConnection.cs b/src/EFCore.SqlServer/Storage/Internal/ISqlServerConnection.cs index 53fc71f1dd5..103feff1778 100644 --- a/src/EFCore.SqlServer/Storage/Internal/ISqlServerConnection.cs +++ b/src/EFCore.SqlServer/Storage/Internal/ISqlServerConnection.cs @@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerBoolTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerBoolTypeMapping.cs index 0dd23ef2ba2..75eb1d23c60 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerBoolTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerBoolTypeMapping.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerByteArrayTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerByteArrayTypeMapping.cs index 1fe4f609685..74188d581e1 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerByteArrayTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerByteArrayTypeMapping.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// @@ -32,10 +34,10 @@ public class SqlServerByteArrayTypeMapping : ByteArrayTypeMapping /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerByteArrayTypeMapping( - [CanBeNull] string storeType = null, + [CanBeNull] string? storeType = null, int? size = null, bool fixedLength = false, - [CanBeNull] ValueComparer comparer = null, + [CanBeNull] ValueComparer? comparer = null, SqlDbType? sqlDbType = null, StoreTypePostfix? storeTypePostfix = null) : this( diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerByteTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerByteTypeMapping.cs index 64fd39348f8..4eb3f9c4c90 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerByteTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerByteTypeMapping.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerConnection.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerConnection.cs index 44e6a2b4a4a..a5af6c61a79 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerConnection.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerConnection.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// @@ -29,8 +31,7 @@ public class SqlServerConnection : RelationalConnection, ISqlServerConnection // Compensate for slow SQL Server database creation private const int DefaultMasterConnectionCommandTimeout = 60; - private static readonly ConcurrentDictionary _multipleActiveResultSetsEnabledMap = - new ConcurrentDictionary(); + private static readonly ConcurrentDictionary _multipleActiveResultSetsEnabledMap = new(); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs index ddf6248c3a7..ebdaa02b1fa 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerDatabaseCreator.cs @@ -14,6 +14,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// @@ -125,7 +127,7 @@ public override bool HasTables() null, null, Dependencies.CurrentContext.Context, - Dependencies.CommandLogger)) + Dependencies.CommandLogger))! != 0); /// @@ -137,7 +139,7 @@ public override bool HasTables() public override Task HasTablesAsync(CancellationToken cancellationToken = default) => Dependencies.ExecutionStrategyFactory.Create().ExecuteAsync( _connection, - async (connection, ct) => (int)await CreateHasTablesCommand() + async (connection, ct) => (int)(await CreateHasTablesCommand() .ExecuteScalarAsync( new RelationalCommandParameterObject( connection, @@ -146,7 +148,7 @@ public override Task HasTablesAsync(CancellationToken cancellationToken = Dependencies.CurrentContext.Context, Dependencies.CommandLogger), cancellationToken: ct) - .ConfigureAwait(false) + .ConfigureAwait(false))! != 0, cancellationToken); private IRelationalCommand CreateHasTablesCommand() diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeOffsetTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeOffsetTypeMapping.cs index 1a48874d551..dc4e79e6e7a 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeOffsetTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeOffsetTypeMapping.cs @@ -7,6 +7,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeTypeMapping.cs index 345820b4375..9a0165ce966 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerDateTimeTypeMapping.cs @@ -8,6 +8,8 @@ using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerDecimalTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerDecimalTypeMapping.cs index b10634c0118..6ee677e250f 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerDecimalTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerDecimalTypeMapping.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerDoubleTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerDoubleTypeMapping.cs index 6c062a79947..32e90e3f981 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerDoubleTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerDoubleTypeMapping.cs @@ -7,6 +7,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategy.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategy.cs index 905030da64e..a28939ef18c 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategy.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategy.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.SqlServer.Internal; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// @@ -49,7 +51,7 @@ public virtual bool RetriesOnFailure public virtual TResult Execute( TState state, Func operation, - Func> verifySucceeded) + Func>? verifySucceeded) { try { @@ -70,7 +72,7 @@ public virtual TResult Execute( public virtual async Task ExecuteAsync( TState state, Func> operation, - Func>> verifySucceeded, + Func>>? verifySucceeded, CancellationToken cancellationToken) { try diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategyFactory.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategyFactory.cs index 3b54fd9532e..7193c761782 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategyFactory.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerExecutionStrategyFactory.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerFloatTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerFloatTypeMapping.cs index 57eaafbc191..ea17e2ce3b6 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerFloatTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerFloatTypeMapping.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerLongTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerLongTypeMapping.cs index c952321baf9..c797f586552 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerLongTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerLongTypeMapping.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerShortTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerShortTypeMapping.cs index f0433736bc1..d524018ae81 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerShortTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerShortTypeMapping.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerSqlGenerationHelper.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerSqlGenerationHelper.cs index 3d02eb99547..5730fd62513 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerSqlGenerationHelper.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerSqlGenerationHelper.cs @@ -9,6 +9,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerSqlVariantTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerSqlVariantTypeMapping.cs index e739912408a..aee63fd8209 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerSqlVariantTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerSqlVariantTypeMapping.cs @@ -4,6 +4,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerStringTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerStringTypeMapping.cs index aa2dd64a7bb..fe32c416d7a 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerStringTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerStringTypeMapping.cs @@ -10,6 +10,8 @@ using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// @@ -34,7 +36,7 @@ public class SqlServerStringTypeMapping : StringTypeMapping /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public SqlServerStringTypeMapping( - [CanBeNull] string storeType = null, + [CanBeNull] string? storeType = null, bool unicode = false, int? size = null, bool fixedLength = false, diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerTimeSpanTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerTimeSpanTypeMapping.cs index 9e2c1da6652..36e1f6a94c4 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerTimeSpanTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerTimeSpanTypeMapping.cs @@ -7,6 +7,8 @@ using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerTransaction.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerTransaction.cs index 905ddc2fab1..b73eb364cab 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerTransaction.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerTransaction.cs @@ -10,6 +10,8 @@ using Microsoft.EntityFrameworkCore.SqlServer.Extensions.Internal; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerTransactionFactory.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerTransactionFactory.cs index 8a208dfaad6..5944313bced 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerTransactionFactory.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerTransactionFactory.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerTransientExceptionDetector.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerTransientExceptionDetector.cs index d1ad34250d5..6d3767c9da3 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerTransientExceptionDetector.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerTransientExceptionDetector.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.Data.SqlClient; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// @@ -18,7 +20,7 @@ public static class SqlServerTransientExceptionDetector /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public static bool ShouldRetryOn([NotNull] Exception ex) + public static bool ShouldRetryOn([CanBeNull] Exception? ex) { if (ex is SqlException sqlException) { diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerTypeMappingSource.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerTypeMappingSource.cs index 5667e47ba32..37c798a9ac5 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerTypeMappingSource.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerTypeMappingSource.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// @@ -44,13 +46,14 @@ private readonly LongTypeMapping _long = new SqlServerLongTypeMapping("bigint", DbType.Int64); private readonly SqlServerByteArrayTypeMapping _rowversion - = new SqlServerByteArrayTypeMapping( + = new( "rowversion", size: 8, comparer: new ValueComparer( (v1, v2) => StructuralComparisons.StructuralEqualityComparer.Equals(v1, v2), v => StructuralComparisons.StructuralEqualityComparer.GetHashCode(v), - v => v == null ? null : v.ToArray()), + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 + v => v == null ? null! : v.ToArray()), storeTypePostfix: StoreTypePostfix.None); private readonly IntTypeMapping _int @@ -221,11 +224,11 @@ public SqlServerTypeMappingSource( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo) + protected override RelationalTypeMapping? FindMapping(in RelationalTypeMappingInfo mappingInfo) => FindRawMapping(mappingInfo)?.Clone(mappingInfo) ?? base.FindMapping(mappingInfo); - private RelationalTypeMapping FindRawMapping(RelationalTypeMappingInfo mappingInfo) + private RelationalTypeMapping? FindRawMapping(RelationalTypeMappingInfo mappingInfo) { var clrType = mappingInfo.ClrType; var storeTypeName = mappingInfo.StoreTypeName; @@ -233,7 +236,7 @@ private RelationalTypeMapping FindRawMapping(RelationalTypeMappingInfo mappingIn if (storeTypeName != null) { var storeTypeNameBase = mappingInfo.StoreTypeNameBase; - if (storeTypeNameBase.StartsWith("[", StringComparison.Ordinal) + if (storeTypeNameBase!.StartsWith("[", StringComparison.Ordinal) && storeTypeNameBase.EndsWith("]", StringComparison.Ordinal)) { storeTypeNameBase = storeTypeNameBase.Substring(1, storeTypeNameBase.Length - 2); @@ -318,17 +321,16 @@ private RelationalTypeMapping FindRawMapping(RelationalTypeMappingInfo mappingIn return null; } - private static readonly List _nameBasesUsingPrecision = - new List - { - "decimal", - "dec", - "numeric", - "datetime2", - "datetimeoffset", - "double precision", - "float" - }; + private static readonly List _nameBasesUsingPrecision = new() + { + "decimal", + "dec", + "numeric", + "datetime2", + "datetimeoffset", + "double precision", + "float" + }; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -336,8 +338,8 @@ private RelationalTypeMapping FindRawMapping(RelationalTypeMappingInfo mappingIn /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override string ParseStoreTypeName( - string storeTypeName, + protected override string? ParseStoreTypeName( + string? storeTypeName, out bool? unicode, out int? size, out int? precision, diff --git a/src/EFCore.SqlServer/Storage/Internal/SqlServerUdtTypeMapping.cs b/src/EFCore.SqlServer/Storage/Internal/SqlServerUdtTypeMapping.cs index bf346613270..93d25c86611 100644 --- a/src/EFCore.SqlServer/Storage/Internal/SqlServerUdtTypeMapping.cs +++ b/src/EFCore.SqlServer/Storage/Internal/SqlServerUdtTypeMapping.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +#nullable enable + namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal { /// @@ -21,7 +23,7 @@ namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal /// public class SqlServerUdtTypeMapping : RelationalTypeMapping { - private static Action _udtTypeNameSetter; + private static Action? _udtTypeNameSetter; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -34,10 +36,10 @@ public SqlServerUdtTypeMapping( [NotNull] string storeType, [NotNull] Func literalGenerator, StoreTypePostfix storeTypePostfix = StoreTypePostfix.None, - [CanBeNull] string udtTypeName = null, - [CanBeNull] ValueConverter converter = null, - [CanBeNull] ValueComparer comparer = null, - [CanBeNull] ValueComparer keyComparer = null, + [CanBeNull] string? udtTypeName = null, + [CanBeNull] ValueConverter? converter = null, + [CanBeNull] ValueComparer? comparer = null, + [CanBeNull] ValueComparer? keyComparer = null, DbType? dbType = null, bool unicode = false, int? size = null, @@ -64,7 +66,7 @@ public SqlServerUdtTypeMapping( protected SqlServerUdtTypeMapping( RelationalTypeMappingParameters parameters, [NotNull] Func literalGenerator, - [CanBeNull] string udtTypeName) + [CanBeNull] string? udtTypeName) : base(parameters) { LiteralGenerator = literalGenerator; @@ -134,7 +136,7 @@ private static Action CreateUdtTypeNameAccessor(Type paramT return Expression.Lambda>( Expression.Call( Expression.Convert(paramParam, paramType), - paramType.GetProperty("UdtTypeName").SetMethod, + paramType.GetProperty("UdtTypeName")!.SetMethod!, valueParam), paramParam, valueParam).Compile(); diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/ISqliteRelationalConnection.cs b/src/EFCore.Sqlite.Core/Storage/Internal/ISqliteRelationalConnection.cs index 41ee2263665..107bd78b4b4 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/ISqliteRelationalConnection.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/ISqliteRelationalConnection.cs @@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDatabaseCreator.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDatabaseCreator.cs index 03076df737c..d35a9c91507 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDatabaseCreator.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDatabaseCreator.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// @@ -116,7 +118,7 @@ public override bool HasTables() null, null, null, - Dependencies.CommandLogger)); + Dependencies.CommandLogger))!; return count != 0; } @@ -129,7 +131,7 @@ public override bool HasTables() /// public override void Delete() { - string path = null; + string? path = null; Dependencies.Connection.Open(); try diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDateTimeOffsetTypeMapping.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDateTimeOffsetTypeMapping.cs index 2898311b958..9b23badab74 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDateTimeOffsetTypeMapping.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDateTimeOffsetTypeMapping.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDateTimeTypeMapping.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDateTimeTypeMapping.cs index e068d9995e9..247831f33db 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDateTimeTypeMapping.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDateTimeTypeMapping.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDecimalTypeMapping.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDecimalTypeMapping.cs index 365615f0e53..dd416bd5c7f 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDecimalTypeMapping.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteDecimalTypeMapping.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteGuidTypeMapping.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteGuidTypeMapping.cs index 8240443ebb7..aec93d74c02 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteGuidTypeMapping.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteGuidTypeMapping.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteRelationalConnection.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteRelationalConnection.cs index 586af92e4e3..0b307f4959b 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteRelationalConnection.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteRelationalConnection.cs @@ -16,6 +16,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// @@ -129,7 +131,7 @@ private void InitializeDbConnection(DbConnection connection) }, isDeterministic: true); - sqliteConnection.CreateFunction( + sqliteConnection.CreateFunction( "ef_mod", (dividend, divisor) => { diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteSqlGenerationHelper.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteSqlGenerationHelper.cs index 21a3df6aa75..40a702436bd 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteSqlGenerationHelper.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteSqlGenerationHelper.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// @@ -49,7 +51,7 @@ public override string StartTransactionStatement /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public override string DelimitIdentifier(string name, string schema) + public override string DelimitIdentifier(string name, string? schema) => base.DelimitIdentifier(name); /// @@ -58,7 +60,7 @@ public override string DelimitIdentifier(string name, string schema) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public override void DelimitIdentifier(StringBuilder builder, string name, string schema) + public override void DelimitIdentifier(StringBuilder builder, string name, string? schema) => base.DelimitIdentifier(builder, name); } } diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteStringTypeMapping.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteStringTypeMapping.cs index 3c8c652c442..b66b47447e5 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteStringTypeMapping.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteStringTypeMapping.cs @@ -8,6 +8,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTypeMappingSource.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTypeMappingSource.cs index ab97137acc5..be0b577c5c9 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTypeMappingSource.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteTypeMappingSource.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// @@ -67,43 +69,41 @@ private static readonly HashSet _spatialiteTypes private const string BlobTypeName = "BLOB"; private const string TextTypeName = "TEXT"; - private static readonly LongTypeMapping _integer = new LongTypeMapping(IntegerTypeName); - private static readonly DoubleTypeMapping _real = new DoubleTypeMapping(RealTypeName); - private static readonly ByteArrayTypeMapping _blob = new ByteArrayTypeMapping(BlobTypeName); - private static readonly SqliteStringTypeMapping _text = new SqliteStringTypeMapping(TextTypeName); + private static readonly LongTypeMapping _integer = new(IntegerTypeName); + private static readonly DoubleTypeMapping _real = new(RealTypeName); + private static readonly ByteArrayTypeMapping _blob = new(BlobTypeName); + private static readonly SqliteStringTypeMapping _text = new(TextTypeName); - private readonly Dictionary _clrTypeMappings - = new Dictionary - { - { typeof(string), _text }, - { typeof(byte[]), _blob }, - { typeof(bool), new BoolTypeMapping(IntegerTypeName) }, - { typeof(byte), new ByteTypeMapping(IntegerTypeName) }, - { typeof(char), new CharTypeMapping(TextTypeName) }, - { typeof(int), new IntTypeMapping(IntegerTypeName) }, - { typeof(long), _integer }, - { typeof(sbyte), new SByteTypeMapping(IntegerTypeName) }, - { typeof(short), new ShortTypeMapping(IntegerTypeName) }, - { typeof(uint), new UIntTypeMapping(IntegerTypeName) }, - { typeof(ulong), new SqliteULongTypeMapping(IntegerTypeName) }, - { typeof(ushort), new UShortTypeMapping(IntegerTypeName) }, - { typeof(DateTime), new SqliteDateTimeTypeMapping(TextTypeName) }, - { typeof(DateTimeOffset), new SqliteDateTimeOffsetTypeMapping(TextTypeName) }, - { typeof(TimeSpan), new TimeSpanTypeMapping(TextTypeName) }, - { typeof(decimal), new SqliteDecimalTypeMapping(TextTypeName) }, - { typeof(double), _real }, - { typeof(float), new FloatTypeMapping(RealTypeName) }, - { typeof(Guid), new SqliteGuidTypeMapping(TextTypeName) } - }; + private readonly Dictionary _clrTypeMappings = new() + { + { typeof(string), _text }, + { typeof(byte[]), _blob }, + { typeof(bool), new BoolTypeMapping(IntegerTypeName) }, + { typeof(byte), new ByteTypeMapping(IntegerTypeName) }, + { typeof(char), new CharTypeMapping(TextTypeName) }, + { typeof(int), new IntTypeMapping(IntegerTypeName) }, + { typeof(long), _integer }, + { typeof(sbyte), new SByteTypeMapping(IntegerTypeName) }, + { typeof(short), new ShortTypeMapping(IntegerTypeName) }, + { typeof(uint), new UIntTypeMapping(IntegerTypeName) }, + { typeof(ulong), new SqliteULongTypeMapping(IntegerTypeName) }, + { typeof(ushort), new UShortTypeMapping(IntegerTypeName) }, + { typeof(DateTime), new SqliteDateTimeTypeMapping(TextTypeName) }, + { typeof(DateTimeOffset), new SqliteDateTimeOffsetTypeMapping(TextTypeName) }, + { typeof(TimeSpan), new TimeSpanTypeMapping(TextTypeName) }, + { typeof(decimal), new SqliteDecimalTypeMapping(TextTypeName) }, + { typeof(double), _real }, + { typeof(float), new FloatTypeMapping(RealTypeName) }, + { typeof(Guid), new SqliteGuidTypeMapping(TextTypeName) } + }; - private readonly Dictionary _storeTypeMappings - = new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { IntegerTypeName, _integer }, - { RealTypeName, _real }, - { BlobTypeName, _blob }, - { TextTypeName, _text } - }; + private readonly Dictionary _storeTypeMappings = new(StringComparer.OrdinalIgnoreCase) + { + { IntegerTypeName, _integer }, + { RealTypeName, _real }, + { BlobTypeName, _blob }, + { TextTypeName, _text } + }; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -133,7 +133,7 @@ public static bool IsSpatialiteType([NotNull] string columnType) /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - protected override RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo) + protected override RelationalTypeMapping? FindMapping(in RelationalTypeMappingInfo mappingInfo) { var mapping = FindRawMapping(mappingInfo); @@ -143,7 +143,7 @@ protected override RelationalTypeMapping FindMapping(in RelationalTypeMappingInf : mapping; } - private RelationalTypeMapping FindRawMapping(RelationalTypeMappingInfo mappingInfo) + private RelationalTypeMapping? FindRawMapping(RelationalTypeMappingInfo mappingInfo) { var clrType = mappingInfo.ClrType; if (clrType != null @@ -181,7 +181,7 @@ private RelationalTypeMapping FindRawMapping(RelationalTypeMappingInfo mappingIn return mapping; } - private readonly Func[] _typeRules = + private readonly Func[] _typeRules = { name => Contains(name, "INT") ? _integer diff --git a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteULongTypeMapping.cs b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteULongTypeMapping.cs index 77f89713ba9..2a82e3af847 100644 --- a/src/EFCore.Sqlite.Core/Storage/Internal/SqliteULongTypeMapping.cs +++ b/src/EFCore.Sqlite.Core/Storage/Internal/SqliteULongTypeMapping.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// diff --git a/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteGeometryTypeMapping.cs b/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteGeometryTypeMapping.cs index 0a48a0081b8..a81cf46b0d9 100644 --- a/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteGeometryTypeMapping.cs +++ b/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteGeometryTypeMapping.cs @@ -14,6 +14,8 @@ using NetTopologySuite.Geometries; using NetTopologySuite.IO; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// @@ -26,7 +28,7 @@ public class SqliteGeometryTypeMapping : RelationalGeometryTypeMappin where TGeometry : Geometry { private static readonly MethodInfo _getBytes - = typeof(DbDataReader).GetRuntimeMethod(nameof(DbDataReader.GetFieldValue), new[] { typeof(int) }) + = typeof(DbDataReader).GetRuntimeMethod(nameof(DbDataReader.GetFieldValue), new[] { typeof(int) })! .MakeGenericMethod(typeof(byte[])); /// @@ -49,7 +51,7 @@ public SqliteGeometryTypeMapping([NotNull] NtsGeometryServices geometryServices, /// protected SqliteGeometryTypeMapping( RelationalTypeMappingParameters parameters, - [CanBeNull] ValueConverter converter) + [CanBeNull] ValueConverter? converter) : base(parameters, converter) { } @@ -128,9 +130,7 @@ protected override Type WKTReaderType => typeof(WKTReader); private static GaiaGeoReader CreateReader(NtsGeometryServices geometryServices) - => new GaiaGeoReader( - geometryServices.DefaultCoordinateSequenceFactory, - geometryServices.DefaultPrecisionModel); + => new(geometryServices.DefaultCoordinateSequenceFactory, geometryServices.DefaultPrecisionModel); private static GaiaGeoWriter CreateWriter(string storeType) { diff --git a/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteNetTopologySuiteTypeMappingSourcePlugin.cs b/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteNetTopologySuiteTypeMappingSourcePlugin.cs index b5300b76d82..6ec4804e499 100644 --- a/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteNetTopologySuiteTypeMappingSourcePlugin.cs +++ b/src/EFCore.Sqlite.NTS/Storage/Internal/SqliteNetTopologySuiteTypeMappingSourcePlugin.cs @@ -10,6 +10,8 @@ using NetTopologySuite; using NetTopologySuite.Geometries; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal { /// @@ -28,42 +30,41 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal /// public class SqliteNetTopologySuiteTypeMappingSourcePlugin : IRelationalTypeMappingSourcePlugin { - private static readonly Dictionary _storeTypeMappings - = new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "GEOMETRY", typeof(Geometry) }, - { "GEOMETRYZ", typeof(Geometry) }, - { "GEOMETRYM", typeof(Geometry) }, - { "GEOMETRYZM", typeof(Geometry) }, - { "GEOMETRYCOLLECTION", typeof(GeometryCollection) }, - { "GEOMETRYCOLLECTIONZ", typeof(GeometryCollection) }, - { "GEOMETRYCOLLECTIONM", typeof(GeometryCollection) }, - { "GEOMETRYCOLLECTIONZM", typeof(GeometryCollection) }, - { "LINESTRING", typeof(LineString) }, - { "LINESTRINGZ", typeof(LineString) }, - { "LINESTRINGM", typeof(LineString) }, - { "LINESTRINGZM", typeof(LineString) }, - { "MULTILINESTRING", typeof(MultiLineString) }, - { "MULTILINESTRINGZ", typeof(MultiLineString) }, - { "MULTILINESTRINGM", typeof(MultiLineString) }, - { "MULTILINESTRINGZM", typeof(MultiLineString) }, - { "MULTIPOINT", typeof(MultiPoint) }, - { "MULTIPOINTZ", typeof(MultiPoint) }, - { "MULTIPOINTM", typeof(MultiPoint) }, - { "MULTIPOINTZM", typeof(MultiPoint) }, - { "MULTIPOLYGON", typeof(MultiPolygon) }, - { "MULTIPOLYGONZ", typeof(MultiPolygon) }, - { "MULTIPOLYGONM", typeof(MultiPolygon) }, - { "MULTIPOLYGONZM", typeof(MultiPolygon) }, - { "POINT", typeof(Point) }, - { "POINTZ", typeof(Point) }, - { "POINTM", typeof(Point) }, - { "POINTZM", typeof(Point) }, - { "POLYGON", typeof(Polygon) }, - { "POLYGONZ", typeof(Polygon) }, - { "POLYGONM", typeof(Polygon) }, - { "POLYGONZM", typeof(Polygon) } - }; + private static readonly Dictionary _storeTypeMappings = new(StringComparer.OrdinalIgnoreCase) + { + { "GEOMETRY", typeof(Geometry) }, + { "GEOMETRYZ", typeof(Geometry) }, + { "GEOMETRYM", typeof(Geometry) }, + { "GEOMETRYZM", typeof(Geometry) }, + { "GEOMETRYCOLLECTION", typeof(GeometryCollection) }, + { "GEOMETRYCOLLECTIONZ", typeof(GeometryCollection) }, + { "GEOMETRYCOLLECTIONM", typeof(GeometryCollection) }, + { "GEOMETRYCOLLECTIONZM", typeof(GeometryCollection) }, + { "LINESTRING", typeof(LineString) }, + { "LINESTRINGZ", typeof(LineString) }, + { "LINESTRINGM", typeof(LineString) }, + { "LINESTRINGZM", typeof(LineString) }, + { "MULTILINESTRING", typeof(MultiLineString) }, + { "MULTILINESTRINGZ", typeof(MultiLineString) }, + { "MULTILINESTRINGM", typeof(MultiLineString) }, + { "MULTILINESTRINGZM", typeof(MultiLineString) }, + { "MULTIPOINT", typeof(MultiPoint) }, + { "MULTIPOINTZ", typeof(MultiPoint) }, + { "MULTIPOINTM", typeof(MultiPoint) }, + { "MULTIPOINTZM", typeof(MultiPoint) }, + { "MULTIPOLYGON", typeof(MultiPolygon) }, + { "MULTIPOLYGONZ", typeof(MultiPolygon) }, + { "MULTIPOLYGONM", typeof(MultiPolygon) }, + { "MULTIPOLYGONZM", typeof(MultiPolygon) }, + { "POINT", typeof(Point) }, + { "POINTZ", typeof(Point) }, + { "POINTM", typeof(Point) }, + { "POINTZM", typeof(Point) }, + { "POLYGON", typeof(Polygon) }, + { "POLYGONZ", typeof(Polygon) }, + { "POLYGONM", typeof(Polygon) }, + { "POLYGONZM", typeof(Polygon) } + }; private readonly NtsGeometryServices _geometryServices; @@ -86,12 +87,12 @@ public SqliteNetTopologySuiteTypeMappingSourcePlugin([NotNull] NtsGeometryServic /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo) + public virtual RelationalTypeMapping? FindMapping(in RelationalTypeMappingInfo mappingInfo) { var clrType = mappingInfo.ClrType; var storeTypeName = mappingInfo.StoreTypeName; - string defaultStoreType = null; - Type defaultClrType = null; + string? defaultStoreType = null; + Type? defaultClrType = null; return (clrType != null && TryGetDefaultStoreType(clrType, out defaultStoreType)) @@ -100,11 +101,11 @@ public virtual RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo ma ? (RelationalTypeMapping)Activator.CreateInstance( typeof(SqliteGeometryTypeMapping<>).MakeGenericType(clrType ?? defaultClrType ?? typeof(Geometry)), _geometryServices, - storeTypeName ?? defaultStoreType ?? "GEOMETRY") + storeTypeName ?? defaultStoreType ?? "GEOMETRY")! : null; } - private static bool TryGetDefaultStoreType(Type type, out string defaultStoreType) + private static bool TryGetDefaultStoreType(Type type, out string? defaultStoreType) { if (typeof(LineString).IsAssignableFrom(type)) { diff --git a/src/EFCore/DbUpdateConcurrencyException.cs b/src/EFCore/DbUpdateConcurrencyException.cs index 9b54d28c583..17843a91694 100644 --- a/src/EFCore/DbUpdateConcurrencyException.cs +++ b/src/EFCore/DbUpdateConcurrencyException.cs @@ -7,6 +7,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Update; +#nullable enable + namespace Microsoft.EntityFrameworkCore { /// @@ -38,7 +40,7 @@ public DbUpdateConcurrencyException([NotNull] string message) /// /// The error message that explains the reason for the exception. /// The exception that is the cause of the current exception. - public DbUpdateConcurrencyException([NotNull] string message, [CanBeNull] Exception innerException) + public DbUpdateConcurrencyException([NotNull] string message, [CanBeNull] Exception? innerException) : base(message, innerException) { } @@ -51,7 +53,7 @@ public DbUpdateConcurrencyException([NotNull] string message, [CanBeNull] Except /// The entries that were involved in the error. public DbUpdateConcurrencyException( [NotNull] string message, - [CanBeNull] Exception innerException, + [CanBeNull] Exception? innerException, [NotNull] IReadOnlyList entries) : base(message, innerException, entries) { diff --git a/src/EFCore/DbUpdateException.cs b/src/EFCore/DbUpdateException.cs index bc026e1ef0a..d74cf11db69 100644 --- a/src/EFCore/DbUpdateException.cs +++ b/src/EFCore/DbUpdateException.cs @@ -10,6 +10,8 @@ using Microsoft.EntityFrameworkCore.Update; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore { /// @@ -19,7 +21,7 @@ namespace Microsoft.EntityFrameworkCore public class DbUpdateException : Exception { [NonSerialized] - private IReadOnlyList _entries; + private IReadOnlyList? _entries; /// /// Initializes a new instance of the class. @@ -42,7 +44,7 @@ public DbUpdateException([NotNull] string message) /// /// The error message that explains the reason for the exception. /// The exception that is the cause of the current exception. - public DbUpdateException([NotNull] string message, [CanBeNull] Exception innerException) + public DbUpdateException([NotNull] string message, [CanBeNull] Exception? innerException) : base(message, innerException) { } @@ -67,7 +69,7 @@ public DbUpdateException( /// The entries that were involved in the error. public DbUpdateException( [NotNull] string message, - [CanBeNull] Exception innerException, + [CanBeNull] Exception? innerException, [NotNull] IReadOnlyList entries) : base(message, innerException) { diff --git a/src/EFCore/Infrastructure/ExpressionExtensions.cs b/src/EFCore/Infrastructure/ExpressionExtensions.cs index af70a95eb51..2c27bd260ec 100644 --- a/src/EFCore/Infrastructure/ExpressionExtensions.cs +++ b/src/EFCore/Infrastructure/ExpressionExtensions.cs @@ -326,7 +326,7 @@ private static TValue ValueBufferTryReadValue( int index, IPropertyBase property) #pragma warning restore IDE0060 // Remove unused parameter - => (TValue)valueBuffer[index]; + => (TValue)valueBuffer[index]!; /// /// diff --git a/src/EFCore/Infrastructure/ICurrentDbContext.cs b/src/EFCore/Infrastructure/ICurrentDbContext.cs index 7c52d4974f1..3e1ee0bb7a5 100644 --- a/src/EFCore/Infrastructure/ICurrentDbContext.cs +++ b/src/EFCore/Infrastructure/ICurrentDbContext.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Infrastructure { /// diff --git a/src/EFCore/Infrastructure/Internal/CurrentDbContext.cs b/src/EFCore/Infrastructure/Internal/CurrentDbContext.cs index ffb62431e2d..fbb9126504c 100644 --- a/src/EFCore/Infrastructure/Internal/CurrentDbContext.cs +++ b/src/EFCore/Infrastructure/Internal/CurrentDbContext.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Infrastructure.Internal { /// diff --git a/src/EFCore/Storage/CoreTypeMapping.cs b/src/EFCore/Storage/CoreTypeMapping.cs index b3f741ee1f6..2b4d0fc4035 100644 --- a/src/EFCore/Storage/CoreTypeMapping.cs +++ b/src/EFCore/Storage/CoreTypeMapping.cs @@ -13,6 +13,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.EntityFrameworkCore.ValueGeneration; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -41,10 +43,10 @@ protected readonly struct CoreTypeMappingParameters /// An optional factory for creating a specific . public CoreTypeMappingParameters( [NotNull] Type clrType, - [CanBeNull] ValueConverter converter = null, - [CanBeNull] ValueComparer comparer = null, - [CanBeNull] ValueComparer keyComparer = null, - [CanBeNull] Func valueGeneratorFactory = null) + [CanBeNull] ValueConverter? converter = null, + [CanBeNull] ValueComparer? comparer = null, + [CanBeNull] ValueComparer? keyComparer = null, + [CanBeNull] Func? valueGeneratorFactory = null) { Check.NotNull(clrType, nameof(clrType)); @@ -68,11 +70,11 @@ public CoreTypeMappingParameters( "Use overload without 'structuralComparer'. Starting with EF Core 5.0, key comparers must implement structural comparisons and deep copies.")] public CoreTypeMappingParameters( [NotNull] Type clrType, - [CanBeNull] ValueConverter converter, - [CanBeNull] ValueComparer comparer, - [CanBeNull] ValueComparer keyComparer, - [CanBeNull] ValueComparer structuralComparer, - [CanBeNull] Func valueGeneratorFactory) + [CanBeNull] ValueConverter? converter, + [CanBeNull] ValueComparer? comparer, + [CanBeNull] ValueComparer? keyComparer, + [CanBeNull] ValueComparer? structuralComparer, + [CanBeNull] Func? valueGeneratorFactory) { Check.NotNull(clrType, nameof(clrType)); @@ -91,30 +93,30 @@ public CoreTypeMappingParameters( /// /// The mapping converter. /// - public ValueConverter Converter { get; } + public ValueConverter? Converter { get; } /// /// The mapping comparer. /// - public ValueComparer Comparer { get; } + public ValueComparer? Comparer { get; } /// /// The mapping key comparer. /// - public ValueComparer KeyComparer { get; } + public ValueComparer? KeyComparer { get; } /// /// The mapping structural comparer. /// [Obsolete("Use KeyComparer. Starting with EF Core 5.0, key comparers must implement structural comparisons and deep copies.")] - public ValueComparer StructuralComparer + public ValueComparer? StructuralComparer => KeyComparer; /// /// An optional factory for creating a specific to use with /// this mapping. /// - public Func ValueGeneratorFactory { get; } + public Func? ValueGeneratorFactory { get; } /// /// Creates a new parameter object with the given @@ -122,7 +124,7 @@ public ValueComparer StructuralComparer /// /// The converter. /// The new parameter object. - public CoreTypeMappingParameters WithComposedConverter([CanBeNull] ValueConverter converter) + public CoreTypeMappingParameters WithComposedConverter([CanBeNull] ValueConverter? converter) => new CoreTypeMappingParameters( ClrType, converter == null ? Converter : converter.ComposeWith(Converter), @@ -131,8 +133,8 @@ public CoreTypeMappingParameters WithComposedConverter([CanBeNull] ValueConverte ValueGeneratorFactory); } - private ValueComparer _comparer; - private ValueComparer _keyComparer; + private ValueComparer? _comparer; + private ValueComparer? _keyComparer; /// /// Initializes a new instance of the class. @@ -175,14 +177,14 @@ protected CoreTypeMapping(CoreTypeMappingParameters parameters) /// Converts types to and from the store whenever this mapping is used. /// May be null if no conversion is needed. /// - public virtual ValueConverter Converter + public virtual ValueConverter? Converter => Parameters.Converter; /// /// An optional factory for creating a specific to use with /// this mapping. /// - public virtual Func ValueGeneratorFactory { get; } + public virtual Func? ValueGeneratorFactory { get; } /// /// A adds custom value snapshotting and comparison for diff --git a/src/EFCore/Storage/Database.cs b/src/EFCore/Storage/Database.cs index 45f473dc105..af4551cfc2f 100644 --- a/src/EFCore/Storage/Database.cs +++ b/src/EFCore/Storage/Database.cs @@ -12,6 +12,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/DatabaseDependencies.cs b/src/EFCore/Storage/DatabaseDependencies.cs index d7f1094756a..ff7e20fe0ef 100644 --- a/src/EFCore/Storage/DatabaseDependencies.cs +++ b/src/EFCore/Storage/DatabaseDependencies.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/DatabaseProvider.cs b/src/EFCore/Storage/DatabaseProvider.cs index 280ad0bb575..6e140558242 100644 --- a/src/EFCore/Storage/DatabaseProvider.cs +++ b/src/EFCore/Storage/DatabaseProvider.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -44,7 +46,7 @@ public DatabaseProvider([NotNull] DatabaseProviderDependencies dependencies) /// for the providers runtime. /// public virtual string Name - => typeof(TOptionsExtension).Assembly.GetName().Name; + => typeof(TOptionsExtension).Assembly.GetName().Name!; /// /// Gets a value indicating whether this database provider has been selected for a given context. diff --git a/src/EFCore/Storage/DatabaseProviderDependencies.cs b/src/EFCore/Storage/DatabaseProviderDependencies.cs index f0ca50b9979..bb431ee68df 100644 --- a/src/EFCore/Storage/DatabaseProviderDependencies.cs +++ b/src/EFCore/Storage/DatabaseProviderDependencies.cs @@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/ExecutionResult.cs b/src/EFCore/Storage/ExecutionResult.cs index 4995937c9b0..af6d1ec95c4 100644 --- a/src/EFCore/Storage/ExecutionResult.cs +++ b/src/EFCore/Storage/ExecutionResult.cs @@ -3,6 +3,8 @@ using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/ExecutionStrategy.cs b/src/EFCore/Storage/ExecutionStrategy.cs index 9aeb2258490..b1a5a3e375d 100644 --- a/src/EFCore/Storage/ExecutionStrategy.cs +++ b/src/EFCore/Storage/ExecutionStrategy.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -146,7 +148,7 @@ public virtual bool RetriesOnFailure public virtual TResult Execute( TState state, Func operation, - Func> verifySucceeded) + Func>? verifySucceeded) { Check.NotNull(operation, nameof(operation)); @@ -162,7 +164,7 @@ public virtual TResult Execute( private TResult ExecuteImplementation( Func operation, - Func> verifySucceeded, + Func>? verifySucceeded, TState state) { while (true) @@ -239,7 +241,7 @@ private TResult ExecuteImplementation( public virtual Task ExecuteAsync( TState state, Func> operation, - Func>> verifySucceeded, + Func>>? verifySucceeded, CancellationToken cancellationToken = default) { Check.NotNull(operation, nameof(operation)); @@ -255,7 +257,7 @@ public virtual Task ExecuteAsync( private async Task ExecuteImplementationAsync( Func> operation, - Func>> verifySucceeded, + Func>>? verifySucceeded, TState state, CancellationToken cancellationToken) { @@ -370,7 +372,7 @@ protected virtual void OnRetry() /// /// if the specified exception could be thrown after a successful execution, otherwise . /// - protected internal virtual bool ShouldVerifySuccessOn([NotNull] Exception exception) + protected internal virtual bool ShouldVerifySuccessOn([CanBeNull] Exception? exception) => ShouldRetryOn(exception); /// @@ -380,7 +382,7 @@ protected internal virtual bool ShouldVerifySuccessOn([NotNull] Exception except /// /// if the specified exception is considered as transient, otherwise . /// - protected internal abstract bool ShouldRetryOn([NotNull] Exception exception); + protected internal abstract bool ShouldRetryOn([CanBeNull] Exception? exception); /// /// Recursively gets InnerException from as long as it is an @@ -393,8 +395,8 @@ protected internal virtual bool ShouldVerifySuccessOn([NotNull] Exception except /// The result from . /// public static TResult CallOnWrappedException( - [NotNull] Exception exception, - [NotNull] Func exceptionHandler) + [CanBeNull] Exception? exception, + [NotNull] Func exceptionHandler) => exception is DbUpdateException dbUpdateException ? CallOnWrappedException(dbUpdateException.InnerException, exceptionHandler) : exceptionHandler(exception); diff --git a/src/EFCore/Storage/ExecutionStrategyDependencies.cs b/src/EFCore/Storage/ExecutionStrategyDependencies.cs index aa5ea92161a..832de2a84d7 100644 --- a/src/EFCore/Storage/ExecutionStrategyDependencies.cs +++ b/src/EFCore/Storage/ExecutionStrategyDependencies.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -56,8 +58,8 @@ public sealed record ExecutionStrategyDependencies [EntityFrameworkInternal] public ExecutionStrategyDependencies( [NotNull] ICurrentDbContext currentContext, - [CanBeNull] IDbContextOptions options, - [CanBeNull] IDiagnosticsLogger logger) + [NotNull] IDbContextOptions options, + [NotNull] IDiagnosticsLogger logger) { Check.NotNull(currentContext, nameof(currentContext)); @@ -69,7 +71,7 @@ public ExecutionStrategyDependencies( /// /// The options for the current instance. /// - public IDbContextOptions Options { get; [param: CanBeNull] init; } + public IDbContextOptions Options { get; [param: NotNull] init; } /// /// Indirection to the current instance. @@ -79,6 +81,6 @@ public ExecutionStrategyDependencies( /// /// The logger. /// - public IDiagnosticsLogger Logger { get; [param: CanBeNull] init; } + public IDiagnosticsLogger Logger { get; [param: NotNull] init; } } } diff --git a/src/EFCore/Storage/ExecutionStrategyExtensions.cs b/src/EFCore/Storage/ExecutionStrategyExtensions.cs index 2a3807136a0..86737448493 100644 --- a/src/EFCore/Storage/ExecutionStrategyExtensions.cs +++ b/src/EFCore/Storage/ExecutionStrategyExtensions.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + // ReSharper disable once CheckNamespace namespace Microsoft.EntityFrameworkCore { @@ -336,11 +338,11 @@ public static TResult Execute( [NotNull] this IExecutionStrategy strategy, [CanBeNull] TState state, [NotNull] Func operation, - [CanBeNull] Func> verifySucceeded) + [CanBeNull] Func>? verifySucceeded) => Check.NotNull(strategy, nameof(strategy)).Execute( state, (c, s) => operation(s), - verifySucceeded == null ? (Func>)null : (c, s) => verifySucceeded(s)); + verifySucceeded == null ? (Func>?)null : (c, s) => verifySucceeded(s)); /// /// Executes the specified asynchronous operation and returns the result. @@ -370,13 +372,13 @@ public static Task ExecuteAsync( [NotNull] this IExecutionStrategy strategy, [CanBeNull] TState state, [NotNull] Func> operation, - [CanBeNull] Func>> verifySucceeded, + [CanBeNull] Func>>? verifySucceeded, CancellationToken cancellationToken = default) => Check.NotNull(strategy, nameof(strategy)).ExecuteAsync( state, (c, s, ct) => operation(s, ct), verifySucceeded == null - ? (Func>>)null + ? (Func>>?)null : (c, s, ct) => verifySucceeded(s, ct), cancellationToken); /// @@ -398,7 +400,7 @@ public static void ExecuteInTransaction( [NotNull] this IExecutionStrategy strategy, [NotNull] Action operation, [NotNull] Func verifySucceeded) - => strategy.ExecuteInTransaction(null, s => operation(), s => verifySucceeded()); + => strategy.ExecuteInTransaction(null, s => operation(), s => verifySucceeded()); /// /// Executes the specified asynchronous operation in a transaction. Allows to check whether @@ -424,7 +426,7 @@ public static Task ExecuteInTransactionAsync( [NotNull] this IExecutionStrategy strategy, [NotNull] Func operation, [NotNull] Func> verifySucceeded) - => strategy.ExecuteInTransactionAsync(null, (s, ct) => operation(), (s, ct) => verifySucceeded()); + => strategy.ExecuteInTransactionAsync(null, (s, ct) => operation(), (s, ct) => verifySucceeded()); /// /// Executes the specified asynchronous operation in a transaction. Allows to check whether @@ -456,7 +458,7 @@ public static Task ExecuteInTransactionAsync( [NotNull] Func operation, [NotNull] Func> verifySucceeded, CancellationToken cancellationToken = default) - => strategy.ExecuteInTransactionAsync( + => strategy.ExecuteInTransactionAsync( null, (s, ct) => operation(ct), (s, ct) => verifySucceeded(ct), cancellationToken); /// @@ -480,7 +482,7 @@ public static TResult ExecuteInTransaction( [NotNull] this IExecutionStrategy strategy, [NotNull] Func operation, [NotNull] Func verifySucceeded) - => strategy.ExecuteInTransaction(null, s => operation(), s => verifySucceeded()); + => strategy.ExecuteInTransaction(null, s => operation(), s => verifySucceeded()); /// /// Executes the specified asynchronous operation in a transaction and returns the result. Allows to check whether @@ -513,7 +515,7 @@ public static Task ExecuteInTransactionAsync( [NotNull] Func> operation, [NotNull] Func> verifySucceeded, CancellationToken cancellationToken = default) - => strategy.ExecuteInTransactionAsync( + => strategy.ExecuteInTransactionAsync( null, (s, ct) => operation(ct), (s, ct) => verifySucceeded(ct), cancellationToken); /// @@ -762,6 +764,7 @@ public ExecutionState( Operation = operation; VerifySucceeded = verifySucceeded; State = state; + Result = default!; } public Func Operation { get; } @@ -781,6 +784,7 @@ public ExecutionStateAsync( Operation = operation; VerifySucceeded = verifySucceeded; State = state; + Result = default!; } public Func> Operation { get; } diff --git a/src/EFCore/Storage/IDatabase.cs b/src/EFCore/Storage/IDatabase.cs index 0394ef0ef22..b4310839ddc 100644 --- a/src/EFCore/Storage/IDatabase.cs +++ b/src/EFCore/Storage/IDatabase.cs @@ -11,6 +11,8 @@ using Microsoft.EntityFrameworkCore.Update; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/IDatabaseCreator.cs b/src/EFCore/Storage/IDatabaseCreator.cs index 5f3469e7f08..d2bb211aba5 100644 --- a/src/EFCore/Storage/IDatabaseCreator.cs +++ b/src/EFCore/Storage/IDatabaseCreator.cs @@ -5,6 +5,8 @@ using System.Threading; using System.Threading.Tasks; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/IDatabaseFacadeDependencies.cs b/src/EFCore/Storage/IDatabaseFacadeDependencies.cs index 49b1ed67165..c5b2fb0e476 100644 --- a/src/EFCore/Storage/IDatabaseFacadeDependencies.cs +++ b/src/EFCore/Storage/IDatabaseFacadeDependencies.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/IDatabaseFacadeDependenciesAccessor.cs b/src/EFCore/Storage/IDatabaseFacadeDependenciesAccessor.cs index 98ece4317b3..bf31ba22086 100644 --- a/src/EFCore/Storage/IDatabaseFacadeDependenciesAccessor.cs +++ b/src/EFCore/Storage/IDatabaseFacadeDependenciesAccessor.cs @@ -1,6 +1,8 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/IDatabaseProvider.cs b/src/EFCore/Storage/IDatabaseProvider.cs index b4ac112a074..7727b2cbbd9 100644 --- a/src/EFCore/Storage/IDatabaseProvider.cs +++ b/src/EFCore/Storage/IDatabaseProvider.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/IDbContextTransaction.cs b/src/EFCore/Storage/IDbContextTransaction.cs index 69a1b076949..c983cbbd31a 100644 --- a/src/EFCore/Storage/IDbContextTransaction.cs +++ b/src/EFCore/Storage/IDbContextTransaction.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/IDbContextTransactionManager.cs b/src/EFCore/Storage/IDbContextTransactionManager.cs index f1a6c3ce17d..179796ed1f0 100644 --- a/src/EFCore/Storage/IDbContextTransactionManager.cs +++ b/src/EFCore/Storage/IDbContextTransactionManager.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -75,6 +77,6 @@ public interface IDbContextTransactionManager : IResettableService /// /// Gets the current transaction. /// - IDbContextTransaction CurrentTransaction { get; } + IDbContextTransaction? CurrentTransaction { get; } } } diff --git a/src/EFCore/Storage/IExecutionStrategy.cs b/src/EFCore/Storage/IExecutionStrategy.cs index 64e71daeb78..52bb8df6dea 100644 --- a/src/EFCore/Storage/IExecutionStrategy.cs +++ b/src/EFCore/Storage/IExecutionStrategy.cs @@ -6,6 +6,8 @@ using System.Threading.Tasks; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -35,7 +37,7 @@ public interface IExecutionStrategy TResult Execute( [CanBeNull] TState state, [NotNull] Func operation, - [CanBeNull] Func> verifySucceeded); + [CanBeNull] Func>? verifySucceeded); /// /// Executes the specified asynchronous operation and returns the result. @@ -63,7 +65,7 @@ TResult Execute( Task ExecuteAsync( [CanBeNull] TState state, [NotNull] Func> operation, - [CanBeNull] Func>> verifySucceeded, + [CanBeNull] Func>>? verifySucceeded, CancellationToken cancellationToken = default); } } diff --git a/src/EFCore/Storage/IExecutionStrategyFactory.cs b/src/EFCore/Storage/IExecutionStrategyFactory.cs index d697fb49187..0cb2184ee30 100644 --- a/src/EFCore/Storage/IExecutionStrategyFactory.cs +++ b/src/EFCore/Storage/IExecutionStrategyFactory.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/ITransactionEnlistmentManager.cs b/src/EFCore/Storage/ITransactionEnlistmentManager.cs index 71517cc5316..e6fba3223da 100644 --- a/src/EFCore/Storage/ITransactionEnlistmentManager.cs +++ b/src/EFCore/Storage/ITransactionEnlistmentManager.cs @@ -4,6 +4,8 @@ using System.Transactions; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -20,12 +22,12 @@ public interface ITransactionEnlistmentManager /// /// The currently enlisted transaction. /// - Transaction EnlistedTransaction { get; } + Transaction? EnlistedTransaction { get; } /// /// Specifies an existing to be used for database operations. /// /// The transaction to be used. - void EnlistTransaction([CanBeNull] Transaction transaction); + void EnlistTransaction([CanBeNull] Transaction? transaction); } } diff --git a/src/EFCore/Storage/ITypeMappingSource.cs b/src/EFCore/Storage/ITypeMappingSource.cs index 8f88711cb2f..1c6dc20c8fb 100644 --- a/src/EFCore/Storage/ITypeMappingSource.cs +++ b/src/EFCore/Storage/ITypeMappingSource.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -35,7 +37,7 @@ public interface ITypeMappingSource /// /// The property. /// The type mapping, or if none was found. - CoreTypeMapping FindMapping([NotNull] IProperty property); + CoreTypeMapping? FindMapping([NotNull] IProperty property); /// /// @@ -49,7 +51,7 @@ public interface ITypeMappingSource /// /// The field or property. /// The type mapping, or if none was found. - CoreTypeMapping FindMapping([NotNull] MemberInfo member); + CoreTypeMapping? FindMapping([NotNull] MemberInfo member); /// /// @@ -63,6 +65,6 @@ public interface ITypeMappingSource /// /// The CLR type. /// The type mapping, or if none was found. - CoreTypeMapping FindMapping([NotNull] Type type); + CoreTypeMapping? FindMapping([NotNull] Type type); } } diff --git a/src/EFCore/Storage/ITypeMappingSourcePlugin.cs b/src/EFCore/Storage/ITypeMappingSourcePlugin.cs index 9a033fed5e9..06b933e4829 100644 --- a/src/EFCore/Storage/ITypeMappingSourcePlugin.cs +++ b/src/EFCore/Storage/ITypeMappingSourcePlugin.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -23,6 +25,6 @@ public interface ITypeMappingSourcePlugin /// /// The mapping info to use to create the mapping. /// The type mapping, or if none could be found. - CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo); + CoreTypeMapping? FindMapping(in TypeMappingInfo mappingInfo); } } diff --git a/src/EFCore/Storage/Internal/DatabaseFacadeDependencies.cs b/src/EFCore/Storage/Internal/DatabaseFacadeDependencies.cs index b75db10851e..d0f1f8f0103 100644 --- a/src/EFCore/Storage/Internal/DatabaseFacadeDependencies.cs +++ b/src/EFCore/Storage/Internal/DatabaseFacadeDependencies.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// diff --git a/src/EFCore/Storage/Internal/ExecutionStrategyFactory.cs b/src/EFCore/Storage/Internal/ExecutionStrategyFactory.cs index bdaa7dcdc2f..389c25b5b35 100644 --- a/src/EFCore/Storage/Internal/ExecutionStrategyFactory.cs +++ b/src/EFCore/Storage/Internal/ExecutionStrategyFactory.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.Internal { /// diff --git a/src/EFCore/Storage/MaterializationContext.cs b/src/EFCore/Storage/MaterializationContext.cs index e8b13085774..6d7a4b6a20e 100644 --- a/src/EFCore/Storage/MaterializationContext.cs +++ b/src/EFCore/Storage/MaterializationContext.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -23,10 +25,10 @@ public readonly struct MaterializationContext /// The for the get method. /// public static readonly MethodInfo GetValueBufferMethod - = typeof(MaterializationContext).GetProperty(nameof(ValueBuffer)).GetMethod; + = typeof(MaterializationContext).GetProperty(nameof(ValueBuffer))!.GetMethod!; internal static readonly PropertyInfo ContextProperty - = typeof(MaterializationContext).GetProperty(nameof(Context)); + = typeof(MaterializationContext).GetProperty(nameof(Context))!; /// /// Creates a new instance. diff --git a/src/EFCore/Storage/NonRetryingExecutionStrategy.cs b/src/EFCore/Storage/NonRetryingExecutionStrategy.cs index 3091ab07ddd..86f48559a79 100644 --- a/src/EFCore/Storage/NonRetryingExecutionStrategy.cs +++ b/src/EFCore/Storage/NonRetryingExecutionStrategy.cs @@ -6,6 +6,8 @@ using System.Threading.Tasks; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -45,7 +47,7 @@ public NonRetryingExecutionStrategy([NotNull] ExecutionStrategyDependencies depe public TResult Execute( TState state, Func operation, - Func> verifySucceeded) + Func>? verifySucceeded) => operation(Dependencies.CurrentContext.Context, state); /// @@ -75,7 +77,7 @@ public Task ExecuteAsync( TState state, Func> operation, Func>> verifySucceeded, + CancellationToken, Task>>? verifySucceeded, CancellationToken cancellationToken = default) => operation(Dependencies.CurrentContext.Context, state, cancellationToken); } diff --git a/src/EFCore/Storage/RetryLimitExceededException.cs b/src/EFCore/Storage/RetryLimitExceededException.cs index a05499a3399..1fd139c7358 100644 --- a/src/EFCore/Storage/RetryLimitExceededException.cs +++ b/src/EFCore/Storage/RetryLimitExceededException.cs @@ -5,6 +5,8 @@ using System.Runtime.Serialization; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/TypeMappingInfo.cs b/src/EFCore/Storage/TypeMappingInfo.cs index e972b404cb0..223279a4bec 100644 --- a/src/EFCore/Storage/TypeMappingInfo.cs +++ b/src/EFCore/Storage/TypeMappingInfo.cs @@ -9,6 +9,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -54,7 +56,7 @@ public TypeMappingInfo( { Check.NotNull(principals, nameof(principals)); - ValueConverter customConverter = null; + ValueConverter? customConverter = null; int? size = null; int? precision = null; int? scale = null; @@ -153,7 +155,7 @@ public TypeMappingInfo( /// Specifies a precision for the mapping, or for default. /// Specifies a scale for the mapping, or for default. public TypeMappingInfo( - [CanBeNull] Type type = null, + [CanBeNull] Type? type = null, bool keyOrIndex = false, bool? unicode = null, int? size = null, @@ -245,7 +247,7 @@ public TypeMappingInfo WithConverter(in ValueConverterInfo converterInfo) /// The CLR type in the model. May be null if type information is conveyed via other means /// (e.g. the store name in a relational type mapping info) /// - public Type ClrType { get; } + public Type? ClrType { get; } /// /// Compares this to another to check if they represent the same mapping. @@ -266,7 +268,7 @@ public bool Equals(TypeMappingInfo other) /// /// The other object. /// if they represent the same mapping; otherwise. - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj != null && obj.GetType() == GetType() && Equals((TypeMappingInfo)obj); diff --git a/src/EFCore/Storage/TypeMappingSource.cs b/src/EFCore/Storage/TypeMappingSource.cs index 4858aef40c3..492bea8dc09 100644 --- a/src/EFCore/Storage/TypeMappingSource.cs +++ b/src/EFCore/Storage/TypeMappingSource.cs @@ -10,6 +10,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.Extensions.DependencyInjection; +#nullable enable + #pragma warning disable 1574, CS0419 // Ambiguous reference in cref attribute namespace Microsoft.EntityFrameworkCore.Storage { @@ -30,8 +32,8 @@ namespace Microsoft.EntityFrameworkCore.Storage /// public abstract class TypeMappingSource : TypeMappingSourceBase { - private readonly ConcurrentDictionary<(TypeMappingInfo, Type, ValueConverter), CoreTypeMapping> _explicitMappings - = new ConcurrentDictionary<(TypeMappingInfo, Type, ValueConverter), CoreTypeMapping>(); + private readonly ConcurrentDictionary<(TypeMappingInfo, Type?, ValueConverter?), CoreTypeMapping?> _explicitMappings + = new ConcurrentDictionary<(TypeMappingInfo, Type?, ValueConverter?), CoreTypeMapping?>(); /// /// Initializes a new instance of the this class. @@ -42,12 +44,12 @@ protected TypeMappingSource([NotNull] TypeMappingSourceDependencies dependencies { } - private CoreTypeMapping FindMappingWithConversion( + private CoreTypeMapping? FindMappingWithConversion( in TypeMappingInfo mappingInfo, - [CanBeNull] IReadOnlyList principals) + [CanBeNull] IReadOnlyList? principals) { - Type providerClrType = null; - ValueConverter customConverter = null; + Type? providerClrType = null; + ValueConverter? customConverter = null; if (principals != null) { for (var i = 0; i < principals.Count; i++) @@ -146,7 +148,7 @@ private CoreTypeMapping FindMappingWithConversion( /// /// The property. /// The type mapping, or if none was found. - public override CoreTypeMapping FindMapping(IProperty property) + public override CoreTypeMapping? FindMapping(IProperty property) { var mapping = property.FindTypeMapping(); if (mapping != null) @@ -173,7 +175,7 @@ public override CoreTypeMapping FindMapping(IProperty property) /// /// The CLR type. /// The type mapping, or if none was found. - public override CoreTypeMapping FindMapping(Type type) + public override CoreTypeMapping? FindMapping(Type type) => FindMappingWithConversion(new TypeMappingInfo(type), null); /// @@ -191,7 +193,7 @@ public override CoreTypeMapping FindMapping(Type type) /// /// The field or property. /// The type mapping, or if none was found. - public override CoreTypeMapping FindMapping(MemberInfo member) + public override CoreTypeMapping? FindMapping(MemberInfo member) => FindMappingWithConversion(new TypeMappingInfo(member), null); } } diff --git a/src/EFCore/Storage/TypeMappingSourceBase.cs b/src/EFCore/Storage/TypeMappingSourceBase.cs index 3a8a8cd856c..dcb851a90d8 100644 --- a/src/EFCore/Storage/TypeMappingSourceBase.cs +++ b/src/EFCore/Storage/TypeMappingSourceBase.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + #pragma warning disable 1574, CS0419 // Ambiguous reference in cref attribute namespace Microsoft.EntityFrameworkCore.Storage { @@ -56,7 +58,7 @@ protected TypeMappingSourceBase([NotNull] TypeMappingSourceDependencies dependen /// /// The mapping info to use to create the mapping. /// The type mapping, or if none could be found. - protected virtual CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo) + protected virtual CoreTypeMapping? FindMapping(in TypeMappingInfo mappingInfo) { foreach (var plugin in Dependencies.Plugins) { @@ -76,8 +78,8 @@ protected virtual CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo) /// The mapping, if any. /// The property, if any. protected virtual void ValidateMapping( - [CanBeNull] CoreTypeMapping mapping, - [CanBeNull] IProperty property) + [CanBeNull] CoreTypeMapping? mapping, + [CanBeNull] IProperty? property) { } @@ -91,7 +93,7 @@ protected virtual void ValidateMapping( /// /// The property. /// The type mapping, or if none was found. - public abstract CoreTypeMapping FindMapping(IProperty property); + public abstract CoreTypeMapping? FindMapping(IProperty property); /// /// @@ -108,7 +110,7 @@ protected virtual void ValidateMapping( /// /// The CLR type. /// The type mapping, or if none was found. - public abstract CoreTypeMapping FindMapping(Type type); + public abstract CoreTypeMapping? FindMapping(Type type); /// /// @@ -125,6 +127,6 @@ protected virtual void ValidateMapping( /// /// The field or property. /// The type mapping, or if none was found. - public abstract CoreTypeMapping FindMapping(MemberInfo member); + public abstract CoreTypeMapping? FindMapping(MemberInfo member); } } diff --git a/src/EFCore/Storage/TypeMappingSourceDependencies.cs b/src/EFCore/Storage/TypeMappingSourceDependencies.cs index dd6556d106c..df4309dd025 100644 --- a/src/EFCore/Storage/TypeMappingSourceDependencies.cs +++ b/src/EFCore/Storage/TypeMappingSourceDependencies.cs @@ -8,6 +8,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// diff --git a/src/EFCore/Storage/ValueBuffer.cs b/src/EFCore/Storage/ValueBuffer.cs index 9ecd40e28de..faeed028809 100644 --- a/src/EFCore/Storage/ValueBuffer.cs +++ b/src/EFCore/Storage/ValueBuffer.cs @@ -8,6 +8,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage { /// @@ -26,14 +28,15 @@ namespace Microsoft.EntityFrameworkCore.Storage /// public static readonly ValueBuffer Empty = new ValueBuffer(); - private readonly object[] _values; + private readonly object?[] _values; /// /// Initializes a new instance of the class. /// /// The list of values for this buffer. - public ValueBuffer([NotNull] object[] values) + public ValueBuffer([NotNull] object?[] values) { + // ReSharper disable once ConditionIsAlwaysTrueOrFalse Check.DebugAssert(values != null, "values is null"); _values = values; @@ -44,7 +47,7 @@ public ValueBuffer([NotNull] object[] values) /// /// The index of the value to get. /// The value at the requested index. - public object this[int index] + public object? this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _values[index]; @@ -53,7 +56,7 @@ public object this[int index] } internal static readonly MethodInfo GetValueMethod - = typeof(ValueBuffer).GetRuntimeProperties().Single(p => p.GetIndexParameters().Length > 0).GetMethod; + = typeof(ValueBuffer).GetRuntimeProperties().Single(p => p.GetIndexParameters().Length > 0).GetMethod!; /// /// Gets the number of values in this buffer. @@ -65,6 +68,7 @@ public int Count /// Gets a value indicating whether the value buffer is empty. /// public bool IsEmpty + // ReSharper disable once ConditionIsAlwaysTrueOrFalse => _values == null; /// @@ -76,7 +80,7 @@ public bool IsEmpty /// /// if the object is a and contains the same values, otherwise . /// - public override bool Equals(object obj) + public override bool Equals(object? obj) => !(obj is null) && obj is ValueBuffer buffer && Equals(buffer); diff --git a/src/EFCore/Storage/ValueConversion/BoolToStringConverter.cs b/src/EFCore/Storage/ValueConversion/BoolToStringConverter.cs index cbfcc5ad5bd..7371a8e51fd 100644 --- a/src/EFCore/Storage/ValueConversion/BoolToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/BoolToStringConverter.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -26,7 +28,7 @@ public class BoolToStringConverter : BoolToTwoValuesConverter public BoolToStringConverter( [NotNull] string falseValue, [NotNull] string trueValue, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base( Check.NotNull(falseValue, nameof(falseValue)), Check.NotNull(trueValue, nameof(trueValue)), @@ -39,7 +41,7 @@ public BoolToStringConverter( /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( + = new( typeof(bool), typeof(string), i => new BoolToStringConverter("0", "1", i.MappingHints), diff --git a/src/EFCore/Storage/ValueConversion/BoolToTwoValuesConverter.cs b/src/EFCore/Storage/ValueConversion/BoolToTwoValuesConverter.cs index 82c367aaea2..c476bbde2d2 100644 --- a/src/EFCore/Storage/ValueConversion/BoolToTwoValuesConverter.cs +++ b/src/EFCore/Storage/ValueConversion/BoolToTwoValuesConverter.cs @@ -5,6 +5,8 @@ using System.Linq.Expressions; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -31,8 +33,8 @@ public class BoolToTwoValuesConverter : ValueConverter> fromProvider = null, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] Expression>? fromProvider = null, + [CanBeNull] ConverterMappingHints? mappingHints = null) : base(ToProvider(falseValue, trueValue), fromProvider ?? ToBool(trueValue), mappingHints) { } diff --git a/src/EFCore/Storage/ValueConversion/BoolToZeroOneConverter.cs b/src/EFCore/Storage/ValueConversion/BoolToZeroOneConverter.cs index d7ab53d9571..75c192d4707 100644 --- a/src/EFCore/Storage/ValueConversion/BoolToZeroOneConverter.cs +++ b/src/EFCore/Storage/ValueConversion/BoolToZeroOneConverter.cs @@ -4,6 +4,8 @@ using System; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -18,7 +20,7 @@ public class BoolToZeroOneConverter : BoolToTwoValuesConverter to create data types with appropriate /// facets for the converted data. /// - public BoolToZeroOneConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public BoolToZeroOneConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base(Zero(), One(), null, mappingHints) { } @@ -27,7 +29,7 @@ public BoolToZeroOneConverter([CanBeNull] ConverterMappingHints mappingHints = n /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(bool), typeof(TProvider), i => new BoolToZeroOneConverter(i.MappingHints)); + = new(typeof(bool), typeof(TProvider), i => new BoolToZeroOneConverter(i.MappingHints)); private static TProvider Zero() { diff --git a/src/EFCore/Storage/ValueConversion/BytesToStringConverter.cs b/src/EFCore/Storage/ValueConversion/BytesToStringConverter.cs index c3f74df20c4..92a2a9dcc82 100644 --- a/src/EFCore/Storage/ValueConversion/BytesToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/BytesToStringConverter.cs @@ -4,6 +4,8 @@ using System; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,10 +21,11 @@ public class BytesToStringConverter : ValueConverter /// facets for the converted data. /// public BytesToStringConverter( - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base( - v => v == null ? null : Convert.ToBase64String(v), - v => v == null ? null : Convert.FromBase64String(v), + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 + v => v == null ? null! : Convert.ToBase64String(v), + v => v == null ? null! : Convert.FromBase64String(v), mappingHints) { } @@ -31,6 +34,6 @@ public BytesToStringConverter( /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(byte[]), typeof(string), i => new BytesToStringConverter(i.MappingHints)); + = new(typeof(byte[]), typeof(string), i => new BytesToStringConverter(i.MappingHints)); } } diff --git a/src/EFCore/Storage/ValueConversion/CastingConverter.cs b/src/EFCore/Storage/ValueConversion/CastingConverter.cs index 1a05db2eb17..fe9906d73de 100644 --- a/src/EFCore/Storage/ValueConversion/CastingConverter.cs +++ b/src/EFCore/Storage/ValueConversion/CastingConverter.cs @@ -5,6 +5,8 @@ using System.Linq.Expressions; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -14,9 +16,9 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion public class CastingConverter : ValueConverter { // ReSharper disable once StaticMemberInGenericType - private static readonly ConverterMappingHints _defaultHints = CreateDefaultHints(); + private static readonly ConverterMappingHints? _defaultHints = CreateDefaultHints(); - private static ConverterMappingHints CreateDefaultHints() + private static ConverterMappingHints? CreateDefaultHints() { if (typeof(TProvider).UnwrapNullableType() == typeof(decimal)) { @@ -41,7 +43,7 @@ private static ConverterMappingHints CreateDefaultHints() /// /// Creates a new instance of this converter. /// - public CastingConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public CastingConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( Convert(), Convert(), @@ -53,8 +55,7 @@ public CastingConverter([CanBeNull] ConverterMappingHints mappingHints = null) /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(TModel), typeof(TProvider), i => new CastingConverter(i.MappingHints), _defaultHints); + = new(typeof(TModel), typeof(TProvider), i => new CastingConverter(i.MappingHints), _defaultHints); private static Expression> Convert() { diff --git a/src/EFCore/Storage/ValueConversion/CharToStringConverter.cs b/src/EFCore/Storage/ValueConversion/CharToStringConverter.cs index bcf2eb713e5..626676a059f 100644 --- a/src/EFCore/Storage/ValueConversion/CharToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/CharToStringConverter.cs @@ -4,6 +4,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -11,8 +13,7 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion /// public class CharToStringConverter : StringCharConverter { - private static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints(size: 1); + private static readonly ConverterMappingHints _defaultHints = new(size: 1); /// /// Creates a new instance of this converter. This converter preserves order. @@ -21,7 +22,7 @@ private static readonly ConverterMappingHints _defaultHints /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public CharToStringConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public CharToStringConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToString(), ToChar(), @@ -33,6 +34,6 @@ public CharToStringConverter([CanBeNull] ConverterMappingHints mappingHints = nu /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(char), typeof(string), i => new CharToStringConverter(i.MappingHints), _defaultHints); + = new(typeof(char), typeof(string), i => new CharToStringConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/ConverterMappingHints.cs b/src/EFCore/Storage/ValueConversion/ConverterMappingHints.cs index 7fb8afdfff7..56686b737b5 100644 --- a/src/EFCore/Storage/ValueConversion/ConverterMappingHints.cs +++ b/src/EFCore/Storage/ValueConversion/ConverterMappingHints.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.ValueGeneration; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -27,7 +29,7 @@ public ConverterMappingHints( int? precision = null, int? scale = null, bool? unicode = null, - [CanBeNull] Func valueGeneratorFactory = null) + [CanBeNull] Func? valueGeneratorFactory = null) { Size = size; Precision = precision; @@ -42,7 +44,7 @@ public ConverterMappingHints( /// /// The hints to add. /// The combined hints. - public virtual ConverterMappingHints With([CanBeNull] ConverterMappingHints hints) + public virtual ConverterMappingHints With([CanBeNull] ConverterMappingHints? hints) => hints == null ? this : new ConverterMappingHints( @@ -76,6 +78,6 @@ public virtual ConverterMappingHints With([CanBeNull] ConverterMappingHints hint /// An optional factory for creating a specific to use for model /// values when this converter is being used. /// - public virtual Func ValueGeneratorFactory { get; } + public virtual Func? ValueGeneratorFactory { get; } } } diff --git a/src/EFCore/Storage/ValueConversion/DateTimeOffsetToBinaryConverter.cs b/src/EFCore/Storage/ValueConversion/DateTimeOffsetToBinaryConverter.cs index 6de471908a4..0757c201c26 100644 --- a/src/EFCore/Storage/ValueConversion/DateTimeOffsetToBinaryConverter.cs +++ b/src/EFCore/Storage/ValueConversion/DateTimeOffsetToBinaryConverter.cs @@ -4,6 +4,8 @@ using System; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class DateTimeOffsetToBinaryConverter : ValueConverter to create data types with appropriate /// facets for the converted data. /// - public DateTimeOffsetToBinaryConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public DateTimeOffsetToBinaryConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( v => ((v.Ticks / 1000) << 11) | ((long)v.Offset.TotalMinutes & 0x7FF), v => new DateTimeOffset( @@ -33,6 +35,6 @@ public DateTimeOffsetToBinaryConverter([CanBeNull] ConverterMappingHints mapping /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(DateTimeOffset), typeof(long), i => new DateTimeOffsetToBinaryConverter(i.MappingHints)); + = new(typeof(DateTimeOffset), typeof(long), i => new DateTimeOffsetToBinaryConverter(i.MappingHints)); } } diff --git a/src/EFCore/Storage/ValueConversion/DateTimeOffsetToBytesConverter.cs b/src/EFCore/Storage/ValueConversion/DateTimeOffsetToBytesConverter.cs index 2b3d09efa75..a39ad9753e4 100644 --- a/src/EFCore/Storage/ValueConversion/DateTimeOffsetToBytesConverter.cs +++ b/src/EFCore/Storage/ValueConversion/DateTimeOffsetToBytesConverter.cs @@ -5,6 +5,8 @@ using System.Linq; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -12,14 +14,9 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion /// public class DateTimeOffsetToBytesConverter : ValueConverter { - private static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints(size: 12); - - private static readonly NumberToBytesConverter _longToBytes - = new NumberToBytesConverter(); - - private static readonly NumberToBytesConverter _shortToBytes - = new NumberToBytesConverter(); + private static readonly ConverterMappingHints _defaultHints = new(size: 12); + private static readonly NumberToBytesConverter _longToBytes = new(); + private static readonly NumberToBytesConverter _shortToBytes = new(); /// /// Creates a new instance of this converter. @@ -28,7 +25,7 @@ private static readonly NumberToBytesConverter _shortToBytes /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public DateTimeOffsetToBytesConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public DateTimeOffsetToBytesConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( v => ToBytes(v), v => v == null ? default : FromBytes(v), @@ -40,8 +37,7 @@ public DateTimeOffsetToBytesConverter([CanBeNull] ConverterMappingHints mappingH /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(DateTimeOffset), typeof(byte[]), i => new DateTimeOffsetToBytesConverter(i.MappingHints), _defaultHints); + = new(typeof(DateTimeOffset), typeof(byte[]), i => new DateTimeOffsetToBytesConverter(i.MappingHints), _defaultHints); private static byte[] ToBytes(DateTimeOffset value) { @@ -52,8 +48,10 @@ private static byte[] ToBytes(DateTimeOffset value) private static DateTimeOffset FromBytes(byte[] bytes) { - var timeBinary = (long)_longToBytes.ConvertFromProvider(bytes); - var offsetMins = (short)_shortToBytes.ConvertFromProvider(bytes.Skip(8).ToArray()); + // TODO-NULLABLE: Conversions will currently only return null for null input, but null input has already been sanitized + // externally (revisit as part of #13850) + var timeBinary = (long)_longToBytes.ConvertFromProvider(bytes)!; + var offsetMins = (short)_shortToBytes.ConvertFromProvider(bytes.Skip(8).ToArray())!; return new DateTimeOffset(DateTime.FromBinary(timeBinary), new TimeSpan(0, offsetMins, 0)); } } diff --git a/src/EFCore/Storage/ValueConversion/DateTimeOffsetToStringConverter.cs b/src/EFCore/Storage/ValueConversion/DateTimeOffsetToStringConverter.cs index 39070010d26..7bc2170924f 100644 --- a/src/EFCore/Storage/ValueConversion/DateTimeOffsetToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/DateTimeOffsetToStringConverter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class DateTimeOffsetToStringConverter : StringDateTimeOffsetConverter to create data types with appropriate /// facets for the converted data. /// - public DateTimeOffsetToStringConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public DateTimeOffsetToStringConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToString(), ToDateTimeOffset(), @@ -31,7 +33,6 @@ public DateTimeOffsetToStringConverter([CanBeNull] ConverterMappingHints mapping /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(DateTimeOffset), typeof(string), i => new DateTimeOffsetToStringConverter(i.MappingHints), _defaultHints); + = new(typeof(DateTimeOffset), typeof(string), i => new DateTimeOffsetToStringConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/DateTimeToBinaryConverter.cs b/src/EFCore/Storage/ValueConversion/DateTimeToBinaryConverter.cs index d8decdd16fa..6f6ea9d77ea 100644 --- a/src/EFCore/Storage/ValueConversion/DateTimeToBinaryConverter.cs +++ b/src/EFCore/Storage/ValueConversion/DateTimeToBinaryConverter.cs @@ -4,6 +4,8 @@ using System; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class DateTimeToBinaryConverter : ValueConverter /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public DateTimeToBinaryConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public DateTimeToBinaryConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( v => v.ToBinary(), v => DateTime.FromBinary(v), @@ -31,6 +33,6 @@ public DateTimeToBinaryConverter([CanBeNull] ConverterMappingHints mappingHints /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(DateTime), typeof(long), i => new DateTimeToBinaryConverter(i.MappingHints)); + = new(typeof(DateTime), typeof(long), i => new DateTimeToBinaryConverter(i.MappingHints)); } } diff --git a/src/EFCore/Storage/ValueConversion/DateTimeToStringConverter.cs b/src/EFCore/Storage/ValueConversion/DateTimeToStringConverter.cs index 1c1e04b257d..5c97063f938 100644 --- a/src/EFCore/Storage/ValueConversion/DateTimeToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/DateTimeToStringConverter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class DateTimeToStringConverter : StringDateTimeConverter to create data types with appropriate /// facets for the converted data. /// - public DateTimeToStringConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public DateTimeToStringConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToString(), ToDateTime(), @@ -31,6 +33,6 @@ public DateTimeToStringConverter([CanBeNull] ConverterMappingHints mappingHints /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(DateTime), typeof(string), i => new DateTimeToStringConverter(i.MappingHints), _defaultHints); + = new(typeof(DateTime), typeof(string), i => new DateTimeToStringConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/DateTimeToTicksConverter.cs b/src/EFCore/Storage/ValueConversion/DateTimeToTicksConverter.cs index 9bd0a2c25ea..bde894ed444 100644 --- a/src/EFCore/Storage/ValueConversion/DateTimeToTicksConverter.cs +++ b/src/EFCore/Storage/ValueConversion/DateTimeToTicksConverter.cs @@ -4,6 +4,8 @@ using System; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -18,7 +20,7 @@ public class DateTimeToTicksConverter : ValueConverter /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public DateTimeToTicksConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public DateTimeToTicksConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( v => v.Ticks, v => new DateTime(v), diff --git a/src/EFCore/Storage/ValueConversion/DefaultValueConverterRegistryDependencies.cs b/src/EFCore/Storage/ValueConversion/DefaultValueConverterRegistryDependencies.cs index 52f196180bb..b35babf6a63 100644 --- a/src/EFCore/Storage/ValueConversion/DefaultValueConverterRegistryDependencies.cs +++ b/src/EFCore/Storage/ValueConversion/DefaultValueConverterRegistryDependencies.cs @@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// diff --git a/src/EFCore/Storage/ValueConversion/EnumToNumberConverter.cs b/src/EFCore/Storage/ValueConversion/EnumToNumberConverter.cs index 19c3ba02c02..6a923832eb8 100644 --- a/src/EFCore/Storage/ValueConversion/EnumToNumberConverter.cs +++ b/src/EFCore/Storage/ValueConversion/EnumToNumberConverter.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -17,9 +19,9 @@ public class EnumToNumberConverter : ValueConverter to create data types with appropriate /// facets for the converted data. /// - public EnumToNumberConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public EnumToNumberConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToNumber(), ToEnum(), @@ -48,8 +50,7 @@ public EnumToNumberConverter([CanBeNull] ConverterMappingHints mappingHints = nu /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(TEnum), typeof(TNumber), i => new EnumToNumberConverter(i.MappingHints), _defaultHints); + = new(typeof(TEnum), typeof(TNumber), i => new EnumToNumberConverter(i.MappingHints), _defaultHints); private static Expression> ToNumber() { diff --git a/src/EFCore/Storage/ValueConversion/EnumToStringConverter.cs b/src/EFCore/Storage/ValueConversion/EnumToStringConverter.cs index 8eb21017791..bfe28dda602 100644 --- a/src/EFCore/Storage/ValueConversion/EnumToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/EnumToStringConverter.cs @@ -4,6 +4,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class EnumToStringConverter : StringEnumConverter to create data types with appropriate /// facets for the converted data. /// - public EnumToStringConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public EnumToStringConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToString(), ToEnum(), @@ -31,6 +33,6 @@ public EnumToStringConverter([CanBeNull] ConverterMappingHints mappingHints = nu /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(TEnum), typeof(string), i => new EnumToStringConverter(i.MappingHints)); + = new(typeof(TEnum), typeof(string), i => new EnumToStringConverter(i.MappingHints)); } } diff --git a/src/EFCore/Storage/ValueConversion/GuidToBytesConverter.cs b/src/EFCore/Storage/ValueConversion/GuidToBytesConverter.cs index f3d3b3bdbbf..c8b7bb678a0 100644 --- a/src/EFCore/Storage/ValueConversion/GuidToBytesConverter.cs +++ b/src/EFCore/Storage/ValueConversion/GuidToBytesConverter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.ValueGeneration; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -13,9 +15,7 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion public class GuidToBytesConverter : ValueConverter { private static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints( - size: 16, - valueGeneratorFactory: (p, t) => new SequentialGuidValueGenerator()); + = new(size: 16, valueGeneratorFactory: (p, t) => new SequentialGuidValueGenerator()); /// /// @@ -31,7 +31,7 @@ private static readonly ConverterMappingHints _defaultHints /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public GuidToBytesConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public GuidToBytesConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( v => v.ToByteArray(), v => v == null ? Guid.Empty : new Guid(v), @@ -43,6 +43,6 @@ public GuidToBytesConverter([CanBeNull] ConverterMappingHints mappingHints = nul /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(Guid), typeof(byte[]), i => new GuidToBytesConverter(i.MappingHints), _defaultHints); + = new(typeof(Guid), typeof(byte[]), i => new GuidToBytesConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/GuidToStringConverter.cs b/src/EFCore/Storage/ValueConversion/GuidToStringConverter.cs index b05c37da450..1710d73c97b 100644 --- a/src/EFCore/Storage/ValueConversion/GuidToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/GuidToStringConverter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -20,7 +22,7 @@ public class GuidToStringConverter : StringGuidConverter /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public GuidToStringConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public GuidToStringConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToString(), ToGuid(), @@ -32,6 +34,6 @@ public GuidToStringConverter([CanBeNull] ConverterMappingHints mappingHints = nu /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(Guid), typeof(string), i => new GuidToStringConverter(i.MappingHints), _defaultHints); + = new(typeof(Guid), typeof(string), i => new GuidToStringConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/IPAddressToBytesConverter.cs b/src/EFCore/Storage/ValueConversion/IPAddressToBytesConverter.cs index 4d1728ee505..d5d3540d8d2 100644 --- a/src/EFCore/Storage/ValueConversion/IPAddressToBytesConverter.cs +++ b/src/EFCore/Storage/ValueConversion/IPAddressToBytesConverter.cs @@ -4,6 +4,8 @@ using System.Net; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -21,10 +23,11 @@ private static readonly ConverterMappingHints _defaultHints /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public IPAddressToBytesConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public IPAddressToBytesConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( - v => v == null ? default : v.GetAddressBytes(), - v => v == null ? default : new IPAddress(v), + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 + v => v == null ? default! : v.GetAddressBytes(), + v => v == null ? default! : new IPAddress(v), _defaultHints.With(mappingHints)) { } @@ -33,10 +36,6 @@ public IPAddressToBytesConverter([CanBeNull] ConverterMappingHints mappingHints /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(IPAddress), - typeof(byte[]), - i => new IPAddressToBytesConverter(i.MappingHints), - _defaultHints); + = new(typeof(IPAddress), typeof(byte[]), i => new IPAddressToBytesConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/IPAddressToStringConverter.cs b/src/EFCore/Storage/ValueConversion/IPAddressToStringConverter.cs index f9aee600334..66b90ea4cf5 100644 --- a/src/EFCore/Storage/ValueConversion/IPAddressToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/IPAddressToStringConverter.cs @@ -6,6 +6,8 @@ using System.Net; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -14,8 +16,7 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion public class IPAddressToStringConverter : ValueConverter { // IPv4-mapped IPv6 addresses can go up to 45 bytes, e.g. 0000:0000:0000:0000:0000:ffff:192.168.1.1 - private static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints(size: 45); + private static readonly ConverterMappingHints _defaultHints = new(size: 45); /// /// Creates a new instance of this converter. @@ -24,7 +25,7 @@ private static readonly ConverterMappingHints _defaultHints /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public IPAddressToStringConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public IPAddressToStringConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToString(), ToIPAddress(), @@ -36,15 +37,14 @@ public IPAddressToStringConverter([CanBeNull] ConverterMappingHints mappingHints /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(IPAddress), - typeof(string), i => new IPAddressToStringConverter(i.MappingHints), - _defaultHints); + = new(typeof(IPAddress), typeof(string), i => new IPAddressToStringConverter(i.MappingHints), _defaultHints); private static new Expression> ToString() - => v => v == null ? default : v.ToString(); + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 + => v => v == null ? default! : v.ToString(); private static Expression> ToIPAddress() - => v => v == null ? default : IPAddress.Parse(v); + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 + => v => v == null ? default! : IPAddress.Parse(v); } } diff --git a/src/EFCore/Storage/ValueConversion/IValueConverterSelector.cs b/src/EFCore/Storage/ValueConversion/IValueConverterSelector.cs index caf9283edac..38dc2b2c129 100644 --- a/src/EFCore/Storage/ValueConversion/IValueConverterSelector.cs +++ b/src/EFCore/Storage/ValueConversion/IValueConverterSelector.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -32,6 +34,6 @@ public interface IValueConverterSelector /// The converters available. IEnumerable Select( [NotNull] Type modelClrType, - [CanBeNull] Type providerClrType = null); + [CanBeNull] Type? providerClrType = null); } } diff --git a/src/EFCore/Storage/ValueConversion/Internal/CompositeValueConverter.cs b/src/EFCore/Storage/ValueConversion/Internal/CompositeValueConverter.cs index a65a7507a07..c44b7a171c3 100644 --- a/src/EFCore/Storage/ValueConversion/Internal/CompositeValueConverter.cs +++ b/src/EFCore/Storage/ValueConversion/Internal/CompositeValueConverter.cs @@ -7,6 +7,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Query; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal { /// @@ -26,7 +28,7 @@ public class CompositeValueConverter : ValueConverte public CompositeValueConverter( [NotNull] ValueConverter converter1, [NotNull] ValueConverter converter2, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base( Compose( (Expression>)converter1.ConvertToProviderExpression, diff --git a/src/EFCore/Storage/ValueConversion/Internal/StringCharConverter.cs b/src/EFCore/Storage/ValueConversion/Internal/StringCharConverter.cs index 01020db4621..363b48ce310 100644 --- a/src/EFCore/Storage/ValueConversion/Internal/StringCharConverter.cs +++ b/src/EFCore/Storage/ValueConversion/Internal/StringCharConverter.cs @@ -6,6 +6,8 @@ using System.Linq.Expressions; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal { /// @@ -25,7 +27,7 @@ public class StringCharConverter : ValueConverter> convertToProviderExpression, [NotNull] Expression> convertFromProviderExpression, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base(convertToProviderExpression, convertFromProviderExpression, mappingHints) { } diff --git a/src/EFCore/Storage/ValueConversion/Internal/StringDateTimeConverter.cs b/src/EFCore/Storage/ValueConversion/Internal/StringDateTimeConverter.cs index 5b6dd3a195b..8bc8a4e0902 100644 --- a/src/EFCore/Storage/ValueConversion/Internal/StringDateTimeConverter.cs +++ b/src/EFCore/Storage/ValueConversion/Internal/StringDateTimeConverter.cs @@ -6,6 +6,8 @@ using System.Linq.Expressions; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal { /// @@ -23,8 +25,7 @@ public class StringDateTimeConverter : ValueConverter // ReSharper disable once StaticMemberInGenericType - protected static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints(size: 48); + protected static readonly ConverterMappingHints _defaultHints = new(size: 48); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -35,7 +36,7 @@ protected static readonly ConverterMappingHints _defaultHints public StringDateTimeConverter( [NotNull] Expression> convertToProviderExpression, [NotNull] Expression> convertFromProviderExpression, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base(convertToProviderExpression, convertFromProviderExpression, mappingHints) { } diff --git a/src/EFCore/Storage/ValueConversion/Internal/StringDateTimeOffsetConverter.cs b/src/EFCore/Storage/ValueConversion/Internal/StringDateTimeOffsetConverter.cs index c8ad2ab3d63..75a851a2d00 100644 --- a/src/EFCore/Storage/ValueConversion/Internal/StringDateTimeOffsetConverter.cs +++ b/src/EFCore/Storage/ValueConversion/Internal/StringDateTimeOffsetConverter.cs @@ -6,6 +6,8 @@ using System.Linq.Expressions; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal { /// @@ -23,8 +25,7 @@ public class StringDateTimeOffsetConverter : ValueConverter // ReSharper disable once StaticMemberInGenericType - protected static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints(size: 48); + protected static readonly ConverterMappingHints _defaultHints = new(size: 48); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -35,7 +36,7 @@ protected static readonly ConverterMappingHints _defaultHints public StringDateTimeOffsetConverter( [NotNull] Expression> convertToProviderExpression, [NotNull] Expression> convertFromProviderExpression, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base(convertToProviderExpression, convertFromProviderExpression, mappingHints) { } diff --git a/src/EFCore/Storage/ValueConversion/Internal/StringEnumConverter.cs b/src/EFCore/Storage/ValueConversion/Internal/StringEnumConverter.cs index 817af01a142..134ccfaba3d 100644 --- a/src/EFCore/Storage/ValueConversion/Internal/StringEnumConverter.cs +++ b/src/EFCore/Storage/ValueConversion/Internal/StringEnumConverter.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal { /// @@ -27,7 +29,7 @@ public class StringEnumConverter : ValueConverter> convertToProviderExpression, [NotNull] Expression> convertFromProviderExpression, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base(convertToProviderExpression, convertFromProviderExpression, mappingHints) { } @@ -39,7 +41,7 @@ public StringEnumConverter( /// doing so can result in application failures when updating to a new Entity Framework Core release. /// protected static new Expression> ToString() - => v => v.ToString(); + => v => v.ToString()!; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/src/EFCore/Storage/ValueConversion/Internal/StringGuidConverter.cs b/src/EFCore/Storage/ValueConversion/Internal/StringGuidConverter.cs index 2a4b959e104..da18bfc5668 100644 --- a/src/EFCore/Storage/ValueConversion/Internal/StringGuidConverter.cs +++ b/src/EFCore/Storage/ValueConversion/Internal/StringGuidConverter.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.ValueGeneration; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal { /// @@ -24,9 +26,7 @@ public class StringGuidConverter : ValueConverter // ReSharper disable once StaticMemberInGenericType protected static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints( - size: 36, - valueGeneratorFactory: (p, t) => new SequentialGuidValueGenerator()); + = new(size: 36, valueGeneratorFactory: (p, t) => new SequentialGuidValueGenerator()); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -37,7 +37,7 @@ protected static readonly ConverterMappingHints _defaultHints public StringGuidConverter( [NotNull] Expression> convertToProviderExpression, [NotNull] Expression> convertFromProviderExpression, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base(convertToProviderExpression, convertFromProviderExpression, mappingHints) { } diff --git a/src/EFCore/Storage/ValueConversion/Internal/StringNumberConverter.cs b/src/EFCore/Storage/ValueConversion/Internal/StringNumberConverter.cs index 23d537fdcd8..7317e8faba4 100644 --- a/src/EFCore/Storage/ValueConversion/Internal/StringNumberConverter.cs +++ b/src/EFCore/Storage/ValueConversion/Internal/StringNumberConverter.cs @@ -6,6 +6,8 @@ using System.Linq.Expressions; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal { /// @@ -23,8 +25,7 @@ public class StringNumberConverter : ValueConverter< /// doing so can result in application failures when updating to a new Entity Framework Core release. /// // ReSharper disable once StaticMemberInGenericType - protected static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints(size: 64); + protected static readonly ConverterMappingHints _defaultHints = new(size: 64); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -35,7 +36,7 @@ protected static readonly ConverterMappingHints _defaultHints public StringNumberConverter( [NotNull] Expression> convertToProviderExpression, [NotNull] Expression> convertFromProviderExpression, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base(convertToProviderExpression, convertFromProviderExpression, mappingHints) { } @@ -59,7 +60,7 @@ protected static Expression> ToNumber() var tryParseMethod = type.GetMethod( nameof(int.TryParse), - new[] { typeof(string), typeof(NumberStyles), typeof(IFormatProvider), type.MakeByRefType() }); + new[] { typeof(string), typeof(NumberStyles), typeof(IFormatProvider), type.MakeByRefType() })!; var parsedVariable = Expression.Variable(type, "parsed"); var param = Expression.Parameter(typeof(string), "v"); @@ -99,8 +100,9 @@ protected static Expression> ToNumber() typeof(uint), typeof(ulong), typeof(ushort), typeof(sbyte), typeof(decimal), typeof(float), typeof(double)); + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 return v => v == null - ? null + ? null! : string.Format( CultureInfo.InvariantCulture, type == typeof(float) || type == typeof(double) ? "{0:R}" : "{0}", diff --git a/src/EFCore/Storage/ValueConversion/Internal/StringTimeSpanConverter.cs b/src/EFCore/Storage/ValueConversion/Internal/StringTimeSpanConverter.cs index 8f488b204ec..97ec686e9b9 100644 --- a/src/EFCore/Storage/ValueConversion/Internal/StringTimeSpanConverter.cs +++ b/src/EFCore/Storage/ValueConversion/Internal/StringTimeSpanConverter.cs @@ -6,6 +6,8 @@ using System.Linq.Expressions; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal { /// @@ -23,8 +25,7 @@ public class StringTimeSpanConverter : ValueConverter // ReSharper disable once StaticMemberInGenericType - protected static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints(size: 48); + protected static readonly ConverterMappingHints _defaultHints = new(size: 48); /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -35,7 +36,7 @@ protected static readonly ConverterMappingHints _defaultHints public StringTimeSpanConverter( [NotNull] Expression> convertToProviderExpression, [NotNull] Expression> convertFromProviderExpression, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base(convertToProviderExpression, convertFromProviderExpression, mappingHints) { } diff --git a/src/EFCore/Storage/ValueConversion/Internal/StringUriConverter.cs b/src/EFCore/Storage/ValueConversion/Internal/StringUriConverter.cs index 65ec1291d92..b94415f6823 100644 --- a/src/EFCore/Storage/ValueConversion/Internal/StringUriConverter.cs +++ b/src/EFCore/Storage/ValueConversion/Internal/StringUriConverter.cs @@ -5,6 +5,8 @@ using System.Linq.Expressions; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal { /// @@ -24,7 +26,7 @@ public class StringUriConverter : ValueConverter> convertToProviderExpression, [NotNull] Expression> convertFromProviderExpression, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base(convertToProviderExpression, convertFromProviderExpression, mappingHints) { } @@ -35,8 +37,9 @@ public StringUriConverter( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 protected static new Expression> ToString() - => v => v != null ? v.ToString() : null; + => v => v != null ? v.ToString() : null!; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -47,9 +50,10 @@ public StringUriConverter( protected static Expression> ToUri() => v => ConvertToUri(v); + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 private static Uri ConvertToUri(string value) => Uri.TryCreate(value, UriKind.RelativeOrAbsolute, out var result) ? result - : default; + : default!; } } diff --git a/src/EFCore/Storage/ValueConversion/NumberToBytesConverter.cs b/src/EFCore/Storage/ValueConversion/NumberToBytesConverter.cs index 77e9c10e97c..39755a408d2 100644 --- a/src/EFCore/Storage/ValueConversion/NumberToBytesConverter.cs +++ b/src/EFCore/Storage/ValueConversion/NumberToBytesConverter.cs @@ -6,6 +6,8 @@ using System.Reflection; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -14,8 +16,7 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion public class NumberToBytesConverter : ValueConverter { // ReSharper disable once StaticMemberInGenericType - private static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints(size: GetByteCount()); + private static readonly ConverterMappingHints _defaultHints = new(size: GetByteCount()); /// /// @@ -32,7 +33,7 @@ private static readonly ConverterMappingHints _defaultHints /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public NumberToBytesConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public NumberToBytesConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base(ToBytes(), ToNumber(), _defaultHints.With(mappingHints)) { } @@ -41,8 +42,7 @@ public NumberToBytesConverter([CanBeNull] ConverterMappingHints mappingHints = n /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(TNumber), typeof(byte[]), i => new NumberToBytesConverter(i.MappingHints), _defaultHints); + = new(typeof(TNumber), typeof(byte[]), i => new NumberToBytesConverter(i.MappingHints), _defaultHints); private static Expression> ToBytes() { @@ -75,7 +75,7 @@ private static Expression> ToBytes() Expression.Call( typeof(BitConverter).GetMethod( nameof(BitConverter.GetBytes), - new[] { type }), + new[] { type })!, input)); if (typeof(TNumber).IsNullableType()) @@ -83,7 +83,7 @@ private static Expression> ToBytes() output = Expression.Condition( Expression.Property( param, - typeof(TNumber).GetProperty(nameof(Nullable.HasValue))), + typeof(TNumber).GetProperty(nameof(Nullable.HasValue))!), output, Expression.Constant(null, typeof(byte[]))); } @@ -111,7 +111,7 @@ private static Expression> ToNumber() : (Expression)Expression.Call( typeof(BitConverter).GetMethod( "To" + type.Name, - new[] { typeof(byte[]), typeof(int) }), + new[] { typeof(byte[]), typeof(int) })!, EnsureEndian(param), Expression.Constant(0)); @@ -151,17 +151,17 @@ private static Expression EnsureEndian(Expression expression) private static readonly MethodInfo _reverseLongMethod = typeof(NumberToBytesConverter).GetMethod( nameof(ReverseLong), - BindingFlags.Static | BindingFlags.NonPublic); + BindingFlags.Static | BindingFlags.NonPublic)!; private static readonly MethodInfo _reverseIntMethod = typeof(NumberToBytesConverter).GetMethod( nameof(ReverseInt), - BindingFlags.Static | BindingFlags.NonPublic); + BindingFlags.Static | BindingFlags.NonPublic)!; private static readonly MethodInfo _reverseShortMethod = typeof(NumberToBytesConverter).GetMethod( nameof(ReverseShort), - BindingFlags.Static | BindingFlags.NonPublic); + BindingFlags.Static | BindingFlags.NonPublic)!; private static byte[] ReverseLong(byte[] bytes) => new[] { bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0] }; @@ -201,7 +201,7 @@ private static byte[] EnsureEndianInt(byte[] bytes) private static readonly MethodInfo _toBytesMethod = typeof(NumberToBytesConverter).GetMethod( nameof(DecimalToBytes), - BindingFlags.Static | BindingFlags.NonPublic); + BindingFlags.Static | BindingFlags.NonPublic)!; private static byte[] DecimalToBytes(decimal value) { @@ -219,7 +219,7 @@ private static byte[] DecimalToBytes(decimal value) private static readonly MethodInfo _toDecimalMethod = typeof(NumberToBytesConverter).GetMethod( nameof(BytesToDecimal), - BindingFlags.Static | BindingFlags.NonPublic); + BindingFlags.Static | BindingFlags.NonPublic)!; private static decimal BytesToDecimal(byte[] bytes) { diff --git a/src/EFCore/Storage/ValueConversion/NumberToStringConverter.cs b/src/EFCore/Storage/ValueConversion/NumberToStringConverter.cs index 2dd5200a464..80b49331197 100644 --- a/src/EFCore/Storage/ValueConversion/NumberToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/NumberToStringConverter.cs @@ -4,6 +4,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class NumberToStringConverter : StringNumberConverter public NumberToStringConverter( - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToString(), ToNumber(), @@ -31,7 +33,6 @@ public NumberToStringConverter( /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(TNumber), typeof(string), i => new NumberToStringConverter(i.MappingHints), _defaultHints); + = new(typeof(TNumber), typeof(string), i => new NumberToStringConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/PhysicalAddressToBytesConverter.cs b/src/EFCore/Storage/ValueConversion/PhysicalAddressToBytesConverter.cs index 9b21b7c38d9..073af0045df 100644 --- a/src/EFCore/Storage/ValueConversion/PhysicalAddressToBytesConverter.cs +++ b/src/EFCore/Storage/ValueConversion/PhysicalAddressToBytesConverter.cs @@ -4,6 +4,8 @@ using System.Net.NetworkInformation; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -11,8 +13,7 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion /// public class PhysicalAddressToBytesConverter : ValueConverter { - private static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints(size: 8); + private static readonly ConverterMappingHints _defaultHints = new(size: 8); /// /// Creates a new instance of this converter. @@ -21,10 +22,11 @@ private static readonly ConverterMappingHints _defaultHints /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public PhysicalAddressToBytesConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public PhysicalAddressToBytesConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( - v => v == null ? default : v.GetAddressBytes(), - v => v == null ? default : new PhysicalAddress(v), + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 + v => v == null ? default! : v.GetAddressBytes(), + v => v == null ? default! : new PhysicalAddress(v), _defaultHints.With(mappingHints)) { } @@ -33,10 +35,6 @@ public PhysicalAddressToBytesConverter([CanBeNull] ConverterMappingHints mapping /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(PhysicalAddress), - typeof(byte[]), - i => new PhysicalAddressToBytesConverter(i.MappingHints), - _defaultHints); + = new(typeof(PhysicalAddress), typeof(byte[]), i => new PhysicalAddressToBytesConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/PhysicalAddressToStringConverter.cs b/src/EFCore/Storage/ValueConversion/PhysicalAddressToStringConverter.cs index 4c8c7e77b8f..e0d34963cc0 100644 --- a/src/EFCore/Storage/ValueConversion/PhysicalAddressToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/PhysicalAddressToStringConverter.cs @@ -6,6 +6,8 @@ using System.Net.NetworkInformation; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -13,8 +15,7 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion /// public class PhysicalAddressToStringConverter : ValueConverter { - private static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints(size: 20); + private static readonly ConverterMappingHints _defaultHints = new(size: 20); /// /// Creates a new instance of this converter. @@ -23,7 +24,7 @@ private static readonly ConverterMappingHints _defaultHints /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public PhysicalAddressToStringConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public PhysicalAddressToStringConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToString(), ToPhysicalAddress(), @@ -35,16 +36,14 @@ public PhysicalAddressToStringConverter([CanBeNull] ConverterMappingHints mappin /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(PhysicalAddress), - typeof(string), - i => new PhysicalAddressToStringConverter(i.MappingHints), - _defaultHints); + = new(typeof(PhysicalAddress), typeof(string), i => new PhysicalAddressToStringConverter(i.MappingHints), _defaultHints); private static new Expression> ToString() - => v => v == null ? default : v.ToString(); + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 + => v => v == null ? default! : v.ToString(); private static Expression> ToPhysicalAddress() - => v => v == null ? default : PhysicalAddress.Parse(v); + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 + => v => v == null ? default! : PhysicalAddress.Parse(v); } } diff --git a/src/EFCore/Storage/ValueConversion/StringToBoolConverter.cs b/src/EFCore/Storage/ValueConversion/StringToBoolConverter.cs index 17e5e5c9eab..ea765b393b4 100644 --- a/src/EFCore/Storage/ValueConversion/StringToBoolConverter.cs +++ b/src/EFCore/Storage/ValueConversion/StringToBoolConverter.cs @@ -4,6 +4,8 @@ using System; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class StringToBoolConverter : ValueConverter /// facets for the converted data. /// public StringToBoolConverter( - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base( v => Convert.ToBoolean(v), v => Convert.ToString(v), @@ -31,6 +33,6 @@ public StringToBoolConverter( /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(string), typeof(bool), i => new StringToBoolConverter(i.MappingHints)); + = new(typeof(string), typeof(bool), i => new StringToBoolConverter(i.MappingHints)); } } diff --git a/src/EFCore/Storage/ValueConversion/StringToBytesConverter.cs b/src/EFCore/Storage/ValueConversion/StringToBytesConverter.cs index aeb996fe08a..d17344f607e 100644 --- a/src/EFCore/Storage/ValueConversion/StringToBytesConverter.cs +++ b/src/EFCore/Storage/ValueConversion/StringToBytesConverter.cs @@ -4,6 +4,8 @@ using System.Text; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -21,10 +23,11 @@ public class StringToBytesConverter : ValueConverter /// public StringToBytesConverter( [NotNull] Encoding encoding, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base( - v => v == null ? null : encoding.GetBytes(v), - v => v == null ? null : encoding.GetString(v), + // TODO-NULLABLE: Null is already sanitized externally, clean up as part of #13850 + v => v == null ? null! : encoding.GetBytes(v), + v => v == null ? null! : encoding.GetString(v), mappingHints) { } @@ -33,6 +36,6 @@ public StringToBytesConverter( /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(string), typeof(byte[]), i => new StringToBytesConverter(Encoding.UTF8, i.MappingHints)); + = new(typeof(string), typeof(byte[]), i => new StringToBytesConverter(Encoding.UTF8, i.MappingHints)); } } diff --git a/src/EFCore/Storage/ValueConversion/StringToCharConverter.cs b/src/EFCore/Storage/ValueConversion/StringToCharConverter.cs index 2b7676ef31e..1f8bc23cb82 100644 --- a/src/EFCore/Storage/ValueConversion/StringToCharConverter.cs +++ b/src/EFCore/Storage/ValueConversion/StringToCharConverter.cs @@ -4,6 +4,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -11,8 +13,7 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion /// public class StringToCharConverter : StringCharConverter { - private static readonly ConverterMappingHints _defaultHints - = new ConverterMappingHints(size: 1); + private static readonly ConverterMappingHints _defaultHints = new(size: 1); /// /// Creates a new instance of this converter. This converter preserves order. @@ -21,7 +22,7 @@ private static readonly ConverterMappingHints _defaultHints /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public StringToCharConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public StringToCharConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToChar(), ToString(), @@ -33,6 +34,6 @@ public StringToCharConverter([CanBeNull] ConverterMappingHints mappingHints = nu /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(string), typeof(char), i => new StringToCharConverter(i.MappingHints), _defaultHints); + = new(typeof(string), typeof(char), i => new StringToCharConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/StringToDateTimeConverter.cs b/src/EFCore/Storage/ValueConversion/StringToDateTimeConverter.cs index 557a8b744de..e6f45fd1399 100644 --- a/src/EFCore/Storage/ValueConversion/StringToDateTimeConverter.cs +++ b/src/EFCore/Storage/ValueConversion/StringToDateTimeConverter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class StringToDateTimeConverter : StringDateTimeConverter to create data types with appropriate /// facets for the converted data. /// - public StringToDateTimeConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public StringToDateTimeConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToDateTime(), ToString(), @@ -31,6 +33,6 @@ public StringToDateTimeConverter([CanBeNull] ConverterMappingHints mappingHints /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(string), typeof(DateTime), i => new StringToDateTimeConverter(i.MappingHints), _defaultHints); + = new(typeof(string), typeof(DateTime), i => new StringToDateTimeConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/StringToDateTimeOffsetConverter.cs b/src/EFCore/Storage/ValueConversion/StringToDateTimeOffsetConverter.cs index 9e3ced83248..5fc4ef7d8a4 100644 --- a/src/EFCore/Storage/ValueConversion/StringToDateTimeOffsetConverter.cs +++ b/src/EFCore/Storage/ValueConversion/StringToDateTimeOffsetConverter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -20,7 +22,7 @@ public class StringToDateTimeOffsetConverter : StringDateTimeOffsetConverter public StringToDateTimeOffsetConverter( - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToDateTimeOffset(), ToString(), @@ -32,7 +34,6 @@ public StringToDateTimeOffsetConverter( /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(string), typeof(DateTimeOffset), i => new StringToDateTimeOffsetConverter(i.MappingHints), _defaultHints); + = new(typeof(string), typeof(DateTimeOffset), i => new StringToDateTimeOffsetConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/StringToEnumConverter.cs b/src/EFCore/Storage/ValueConversion/StringToEnumConverter.cs index 2b57412a8b8..7102e267561 100644 --- a/src/EFCore/Storage/ValueConversion/StringToEnumConverter.cs +++ b/src/EFCore/Storage/ValueConversion/StringToEnumConverter.cs @@ -4,6 +4,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class StringToEnumConverter : StringEnumConverter to create data types with appropriate /// facets for the converted data. /// - public StringToEnumConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public StringToEnumConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToEnum(), ToString(), @@ -31,6 +33,6 @@ public StringToEnumConverter([CanBeNull] ConverterMappingHints mappingHints = nu /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(string), typeof(TEnum), i => new StringToEnumConverter(i.MappingHints)); + = new(typeof(string), typeof(TEnum), i => new StringToEnumConverter(i.MappingHints)); } } diff --git a/src/EFCore/Storage/ValueConversion/StringToGuidConverter.cs b/src/EFCore/Storage/ValueConversion/StringToGuidConverter.cs index 4f6a86da6a0..5a43dd566c3 100644 --- a/src/EFCore/Storage/ValueConversion/StringToGuidConverter.cs +++ b/src/EFCore/Storage/ValueConversion/StringToGuidConverter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -20,7 +22,7 @@ public class StringToGuidConverter : StringGuidConverter /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public StringToGuidConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public StringToGuidConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToGuid(), ToString(), @@ -32,6 +34,6 @@ public StringToGuidConverter([CanBeNull] ConverterMappingHints mappingHints = nu /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(string), typeof(Guid), i => new StringToGuidConverter(i.MappingHints), _defaultHints); + = new(typeof(string), typeof(Guid), i => new StringToGuidConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/StringToNumberConverter.cs b/src/EFCore/Storage/ValueConversion/StringToNumberConverter.cs index 25ca9fb5613..f6ecbb8dc3f 100644 --- a/src/EFCore/Storage/ValueConversion/StringToNumberConverter.cs +++ b/src/EFCore/Storage/ValueConversion/StringToNumberConverter.cs @@ -4,6 +4,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class StringToNumberConverter : StringNumberConverter public StringToNumberConverter( - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToNumber(), ToString(), @@ -31,7 +33,6 @@ public StringToNumberConverter( /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo( - typeof(string), typeof(TNumber), i => new StringToNumberConverter(i.MappingHints), _defaultHints); + = new(typeof(string), typeof(TNumber), i => new StringToNumberConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/StringToTimeSpanConverter.cs b/src/EFCore/Storage/ValueConversion/StringToTimeSpanConverter.cs index 62a0ded7146..1fc964f1653 100644 --- a/src/EFCore/Storage/ValueConversion/StringToTimeSpanConverter.cs +++ b/src/EFCore/Storage/ValueConversion/StringToTimeSpanConverter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class StringToTimeSpanConverter : StringTimeSpanConverter to create data types with appropriate /// facets for the converted data. /// - public StringToTimeSpanConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public StringToTimeSpanConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToTimeSpan(), ToString(), @@ -31,6 +33,6 @@ public StringToTimeSpanConverter([CanBeNull] ConverterMappingHints mappingHints /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(string), typeof(TimeSpan), i => new StringToTimeSpanConverter(i.MappingHints), _defaultHints); + = new(typeof(string), typeof(TimeSpan), i => new StringToTimeSpanConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/StringToUriConverter.cs b/src/EFCore/Storage/ValueConversion/StringToUriConverter.cs index 6c7ef8dc337..19844160684 100644 --- a/src/EFCore/Storage/ValueConversion/StringToUriConverter.cs +++ b/src/EFCore/Storage/ValueConversion/StringToUriConverter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class StringToUriConverter : StringUriConverter /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public StringToUriConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public StringToUriConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToUri(), ToString(), @@ -31,6 +33,6 @@ public StringToUriConverter([CanBeNull] ConverterMappingHints mappingHints = nul /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(string), typeof(Uri), i => new StringToUriConverter(i.MappingHints)); + = new(typeof(string), typeof(Uri), i => new StringToUriConverter(i.MappingHints)); } } diff --git a/src/EFCore/Storage/ValueConversion/TimeSpanToStringConverter.cs b/src/EFCore/Storage/ValueConversion/TimeSpanToStringConverter.cs index 5236045d2af..894adc25eca 100644 --- a/src/EFCore/Storage/ValueConversion/TimeSpanToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/TimeSpanToStringConverter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class TimeSpanToStringConverter : StringTimeSpanConverter to create data types with appropriate /// facets for the converted data. /// - public TimeSpanToStringConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public TimeSpanToStringConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToString(), ToTimeSpan(), @@ -31,6 +33,6 @@ public TimeSpanToStringConverter([CanBeNull] ConverterMappingHints mappingHints /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(TimeSpan), typeof(string), i => new TimeSpanToStringConverter(i.MappingHints), _defaultHints); + = new(typeof(TimeSpan), typeof(string), i => new TimeSpanToStringConverter(i.MappingHints), _defaultHints); } } diff --git a/src/EFCore/Storage/ValueConversion/TimeSpanToTicksConverter.cs b/src/EFCore/Storage/ValueConversion/TimeSpanToTicksConverter.cs index b36a0974afe..d80d9f93522 100644 --- a/src/EFCore/Storage/ValueConversion/TimeSpanToTicksConverter.cs +++ b/src/EFCore/Storage/ValueConversion/TimeSpanToTicksConverter.cs @@ -4,6 +4,8 @@ using System; using JetBrains.Annotations; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -18,7 +20,7 @@ public class TimeSpanToTicksConverter : ValueConverter /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public TimeSpanToTicksConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public TimeSpanToTicksConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base(v => v.Ticks, v => new TimeSpan(v), mappingHints) { } @@ -27,6 +29,6 @@ public TimeSpanToTicksConverter([CanBeNull] ConverterMappingHints mappingHints = /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(TimeSpan), typeof(long), i => new TimeSpanToTicksConverter(i.MappingHints)); + = new(typeof(TimeSpan), typeof(long), i => new TimeSpanToTicksConverter(i.MappingHints)); } } diff --git a/src/EFCore/Storage/ValueConversion/UriToStringConverter.cs b/src/EFCore/Storage/ValueConversion/UriToStringConverter.cs index 323dbe960ba..73fda73add1 100644 --- a/src/EFCore/Storage/ValueConversion/UriToStringConverter.cs +++ b/src/EFCore/Storage/ValueConversion/UriToStringConverter.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -19,7 +21,7 @@ public class UriToStringConverter : StringUriConverter /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public UriToStringConverter([CanBeNull] ConverterMappingHints mappingHints = null) + public UriToStringConverter([CanBeNull] ConverterMappingHints? mappingHints = null) : base( ToString(), ToUri(), @@ -31,6 +33,6 @@ public UriToStringConverter([CanBeNull] ConverterMappingHints mappingHints = nul /// A for the default use of this converter. /// public static ValueConverterInfo DefaultInfo { get; } - = new ValueConverterInfo(typeof(Uri), typeof(string), i => new UriToStringConverter(i.MappingHints)); + = new(typeof(Uri), typeof(string), i => new UriToStringConverter(i.MappingHints)); } } diff --git a/src/EFCore/Storage/ValueConversion/ValueConverter.cs b/src/EFCore/Storage/ValueConversion/ValueConverter.cs index 4c71b1387f7..328dda34057 100644 --- a/src/EFCore/Storage/ValueConversion/ValueConverter.cs +++ b/src/EFCore/Storage/ValueConversion/ValueConverter.cs @@ -10,6 +10,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -38,7 +40,7 @@ public abstract class ValueConverter protected ValueConverter( [NotNull] LambdaExpression convertToProviderExpression, [NotNull] LambdaExpression convertFromProviderExpression, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) { Check.NotNull(convertToProviderExpression, nameof(convertToProviderExpression)); Check.NotNull(convertFromProviderExpression, nameof(convertFromProviderExpression)); @@ -52,13 +54,13 @@ protected ValueConverter( /// Gets the function to convert objects when writing data to the store, /// setup to handle nulls, boxing, and non-exact matches of simple types. /// - public abstract Func ConvertToProvider { get; } + public abstract Func ConvertToProvider { get; } /// /// Gets the function to convert objects when reading data from the store, /// setup to handle nulls, boxing, and non-exact matches of simple types. /// - public abstract Func ConvertFromProvider { get; } + public abstract Func ConvertFromProvider { get; } /// /// Gets the expression to convert objects when writing data to the store, @@ -88,7 +90,7 @@ protected ValueConverter( /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public virtual ConverterMappingHints MappingHints { get; } + public virtual ConverterMappingHints? MappingHints { get; } /// /// Checks that the type used with a value converter is supported by that converter and throws if not. @@ -125,7 +127,7 @@ protected static Type CheckTypeSupported( /// The second converter. /// The composed converter. public virtual ValueConverter ComposeWith( - [CanBeNull] ValueConverter secondConverter) + [CanBeNull] ValueConverter? secondConverter) { if (secondConverter == null) { @@ -150,7 +152,7 @@ var firstConverter typeof(CastingConverter<,>).MakeGenericType( ProviderClrType, secondConverter.ModelClrType), - MappingHints)) + MappingHints)!) : this; return (ValueConverter)Activator.CreateInstance( @@ -162,7 +164,7 @@ var firstConverter secondConverter, secondConverter.MappingHints == null ? firstConverter.MappingHints - : secondConverter.MappingHints.With(firstConverter.MappingHints)); + : secondConverter.MappingHints.With(firstConverter.MappingHints))!; } } } diff --git a/src/EFCore/Storage/ValueConversion/ValueConverterInfo.cs b/src/EFCore/Storage/ValueConversion/ValueConverterInfo.cs index 53474962d6a..d3618972345 100644 --- a/src/EFCore/Storage/ValueConversion/ValueConverterInfo.cs +++ b/src/EFCore/Storage/ValueConversion/ValueConverterInfo.cs @@ -5,6 +5,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Utilities; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -29,7 +31,7 @@ public ValueConverterInfo( [NotNull] Type modelClrType, [NotNull] Type providerClrType, [NotNull] Func factory, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) { _factory = factory; Check.NotNull(modelClrType, nameof(modelClrType)); @@ -55,7 +57,7 @@ public ValueConverterInfo( /// Hints that can be used by the to create data types with appropriate /// facets for the converted data. /// - public ConverterMappingHints MappingHints { get; } + public ConverterMappingHints? MappingHints { get; } /// /// Creates an instance of the . diff --git a/src/EFCore/Storage/ValueConversion/ValueConverterSelector.cs b/src/EFCore/Storage/ValueConversion/ValueConverterSelector.cs index 42b0593d06f..a796ccd4d62 100644 --- a/src/EFCore/Storage/ValueConversion/ValueConverterSelector.cs +++ b/src/EFCore/Storage/ValueConversion/ValueConverterSelector.cs @@ -12,6 +12,8 @@ using Microsoft.EntityFrameworkCore.Utilities; using Microsoft.Extensions.DependencyInjection; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -28,8 +30,7 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion /// public class ValueConverterSelector : IValueConverterSelector { - private readonly ConcurrentDictionary<(Type ModelClrType, Type ProviderClrType), ValueConverterInfo> _converters - = new ConcurrentDictionary<(Type, Type), ValueConverterInfo>(); + private readonly ConcurrentDictionary<(Type ModelClrType, Type ProviderClrType), ValueConverterInfo> _converters = new(); private static readonly Type[] _signedPreferred = { typeof(sbyte), typeof(short), typeof(int), typeof(long), typeof(decimal) }; @@ -86,7 +87,7 @@ public ValueConverterSelector([NotNull] ValueConverterSelectorDependencies depen /// The converters available. public virtual IEnumerable Select( Type modelClrType, - Type providerClrType = null) + Type? providerClrType = null) { Check.NotNull(modelClrType, nameof(modelClrType)); @@ -189,10 +190,7 @@ public virtual IEnumerable Select( { yield return _converters.GetOrAdd( (typeof(string), providerClrType), - k => (ValueConverterInfo)typeof(StringToEnumConverter<>) - .MakeGenericType(k.ProviderClrType) - .GetAnyProperty("DefaultInfo") - .GetValue(null)); + k => GetDefaultValueConverterInfo(typeof(StringToEnumConverter<>).MakeGenericType(k.ProviderClrType))); } else if (_numerics.Contains(providerClrType)) { @@ -349,7 +347,7 @@ public virtual IEnumerable Select( private IEnumerable ForChar( Type underlyingModelType, - Type underlyingProviderType) + Type? underlyingProviderType) { if (underlyingProviderType == null || underlyingProviderType == typeof(string)) @@ -371,7 +369,7 @@ private IEnumerable ForChar( private IEnumerable CharToBytes( Type underlyingModelType, - Type underlyingProviderType) + Type? underlyingProviderType) { if (underlyingProviderType == null || underlyingProviderType == typeof(byte[])) @@ -384,17 +382,14 @@ private IEnumerable CharToBytes( private IEnumerable EnumToStringOrBytes( Type underlyingModelType, - Type underlyingProviderType) + Type? underlyingProviderType) { if (underlyingProviderType == null || underlyingProviderType == typeof(string)) { yield return _converters.GetOrAdd( (underlyingModelType, typeof(string)), - k => (ValueConverterInfo)typeof(EnumToStringConverter<>) - .MakeGenericType(k.ModelClrType) - .GetAnyProperty("DefaultInfo") - .GetValue(null)); + k => GetDefaultValueConverterInfo(typeof(EnumToStringConverter<>).MakeGenericType(k.ModelClrType))); } if (underlyingProviderType == null @@ -404,15 +399,11 @@ private IEnumerable EnumToStringOrBytes( (underlyingModelType, typeof(byte[])), k => { - var toNumber = (ValueConverterInfo)typeof(EnumToNumberConverter<,>) - .MakeGenericType(k.ModelClrType, k.ModelClrType.GetEnumUnderlyingType()) - .GetAnyProperty("DefaultInfo") - .GetValue(null); + var toNumber = GetDefaultValueConverterInfo( + typeof(EnumToNumberConverter<,>).MakeGenericType(k.ModelClrType, k.ModelClrType.GetEnumUnderlyingType())); - var toBytes = (ValueConverterInfo)typeof(NumberToBytesConverter<>) - .MakeGenericType(k.ModelClrType.GetEnumUnderlyingType()) - .GetAnyProperty("DefaultInfo") - .GetValue(null); + var toBytes = GetDefaultValueConverterInfo( + typeof(NumberToBytesConverter<>).MakeGenericType(k.ModelClrType.GetEnumUnderlyingType())); return new ValueConverterInfo( underlyingModelType, @@ -425,17 +416,14 @@ private IEnumerable EnumToStringOrBytes( private IEnumerable NumberToStringOrBytes( Type underlyingModelType, - Type underlyingProviderType) + Type? underlyingProviderType) { if (underlyingProviderType == null || underlyingProviderType == typeof(string)) { yield return _converters.GetOrAdd( (underlyingModelType, typeof(string)), - k => (ValueConverterInfo)typeof(NumberToStringConverter<>) - .MakeGenericType(k.ModelClrType) - .GetAnyProperty("DefaultInfo") - .GetValue(null)); + k => GetDefaultValueConverterInfo(typeof(NumberToStringConverter<>).MakeGenericType(k.ModelClrType))); } if (underlyingProviderType == null @@ -443,18 +431,15 @@ private IEnumerable NumberToStringOrBytes( { yield return _converters.GetOrAdd( (underlyingModelType, typeof(byte[])), - k => (ValueConverterInfo)typeof(NumberToBytesConverter<>) - .MakeGenericType(k.ModelClrType) - .GetAnyProperty("DefaultInfo") - .GetValue(null)); + k => GetDefaultValueConverterInfo(typeof(NumberToBytesConverter<>).MakeGenericType(k.ModelClrType))); } } private IEnumerable FindNumericConventions( Type modelType, - Type providerType, + Type? providerType, Type converterType, - Func> afterPreferred) + Func>? afterPreferred) { var usedTypes = new List { modelType }; // List not hash because few members var underlyingModelType = modelType.UnwrapEnumType(); @@ -539,11 +524,10 @@ private IEnumerable FindNumericConventions( { yield return _converters.GetOrAdd( (modelType, numeric), - k => (ValueConverterInfo)(converterType.GetTypeInfo().GenericTypeParameters.Length == 1 + k => GetDefaultValueConverterInfo( + converterType.GetTypeInfo().GenericTypeParameters.Length == 1 ? converterType.MakeGenericType(k.ProviderClrType) - : converterType.MakeGenericType(k.ModelClrType, k.ProviderClrType)) - .GetAnyProperty("DefaultInfo") - .GetValue(null)); + : converterType.MakeGenericType(k.ModelClrType, k.ProviderClrType))); } } } @@ -551,7 +535,7 @@ private IEnumerable FindNumericConventions( private IEnumerable FindPreferredConversions( Type[] candidateTypes, Type modelType, - Type providerType, + Type? providerType, Type converterType) { var underlyingModelType = modelType.UnwrapEnumType(); @@ -572,13 +556,14 @@ private IEnumerable FindPreferredConversions( { yield return _converters.GetOrAdd( (modelType, candidateTypes[i]), - k => (ValueConverterInfo)converterType.MakeGenericType(k.ModelClrType, k.ProviderClrType) - .GetAnyProperty("DefaultInfo") - .GetValue(null)); + k => GetDefaultValueConverterInfo(converterType.MakeGenericType(k.ModelClrType, k.ProviderClrType))); } } } } } + + private static ValueConverterInfo GetDefaultValueConverterInfo(Type converterTypeInfo) + => (ValueConverterInfo)converterTypeInfo.GetAnyProperty("DefaultInfo")!.GetValue(null)!; } } diff --git a/src/EFCore/Storage/ValueConversion/ValueConverter`.cs b/src/EFCore/Storage/ValueConversion/ValueConverter`.cs index 03a6342079c..80a183b949b 100644 --- a/src/EFCore/Storage/ValueConversion/ValueConverter`.cs +++ b/src/EFCore/Storage/ValueConversion/ValueConverter`.cs @@ -6,6 +6,8 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Internal; +#nullable enable + namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion { /// @@ -14,8 +16,8 @@ namespace Microsoft.EntityFrameworkCore.Storage.ValueConversion /// public class ValueConverter : ValueConverter { - private Func _convertToProvider; - private Func _convertFromProvider; + private Func? _convertToProvider; + private Func? _convertFromProvider; /// /// Initializes a new instance of the class. @@ -29,17 +31,17 @@ public class ValueConverter : ValueConverter public ValueConverter( [NotNull] Expression> convertToProviderExpression, [NotNull] Expression> convertFromProviderExpression, - [CanBeNull] ConverterMappingHints mappingHints = null) + [CanBeNull] ConverterMappingHints? mappingHints = null) : base(convertToProviderExpression, convertFromProviderExpression, mappingHints) { } - private static Func SanitizeConverter(Expression> convertExpression) + private static Func SanitizeConverter(Expression> convertExpression) { var compiled = convertExpression.Compile(); return v => v == null - ? (object)null + ? (object?)null : compiled(Sanitize(v)); } @@ -56,7 +58,7 @@ private static T Sanitize(object value) /// Gets the function to convert objects when writing data to the store, /// setup to handle nulls, boxing, and non-exact matches of simple types. /// - public override Func ConvertToProvider + public override Func ConvertToProvider => NonCapturingLazyInitializer.EnsureInitialized( ref _convertToProvider, this, c => SanitizeConverter(c.ConvertToProviderExpression)); @@ -64,7 +66,7 @@ public override Func ConvertToProvider /// Gets the function to convert objects when reading data from the store, /// setup to handle nulls, boxing, and non-exact matches of simple types. /// - public override Func ConvertFromProvider + public override Func ConvertFromProvider => NonCapturingLazyInitializer.EnsureInitialized( ref _convertFromProvider, this, c => SanitizeConverter(c.ConvertFromProviderExpression));