diff --git a/Directory.Packages.props b/Directory.Packages.props index 7504e504c6..00189bd576 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,6 +1,6 @@ - 6.0.0-preview.3.21163.3 + 6.0.0-preview.3.21165.3 6.0.0-preview.3.21164.8 6.0.0-ci.20210310T201503 diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 0288a72482..c4a7c218e8 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -5,6 +5,7 @@ true snupkg true + enable diff --git a/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.cs b/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.cs index 5e987db89a..40649b5cdf 100644 --- a/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.cs +++ b/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.cs @@ -22,8 +22,8 @@ public static class NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions /// public static NpgsqlDbContextOptionsBuilder UseNetTopologySuite( [NotNull] this NpgsqlDbContextOptionsBuilder optionsBuilder, - [CanBeNull] CoordinateSequenceFactory coordinateSequenceFactory = null, - [CanBeNull] PrecisionModel precisionModel = null, + [CanBeNull] CoordinateSequenceFactory? coordinateSequenceFactory = null, + [CanBeNull] PrecisionModel? precisionModel = null, Ordinates handleOrdinates = Ordinates.None, bool geographyAsDefault = false) { diff --git a/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteServiceCollectionExtensions.cs b/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteServiceCollectionExtensions.cs index 042e8af3d8..74e4874b51 100644 --- a/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteServiceCollectionExtensions.cs +++ b/src/EFCore.PG.NTS/Extensions/NpgsqlNetTopologySuiteServiceCollectionExtensions.cs @@ -27,7 +27,7 @@ public static IServiceCollection AddEntityFrameworkNpgsqlNetTopologySuite( Check.NotNull(serviceCollection, nameof(serviceCollection)); new EntityFrameworkRelationalServicesBuilder(serviceCollection) - .TryAdd(p => p.GetService()) + .TryAdd(p => p.GetRequiredService()) .TryAddProviderSpecificServices( x => x .TryAddSingletonEnumerable() diff --git a/src/EFCore.PG.NTS/Infrastructure/Internal/NpgsqlNetTopologySuiteOptionsExtension.cs b/src/EFCore.PG.NTS/Infrastructure/Internal/NpgsqlNetTopologySuiteOptionsExtension.cs index 98c7150d47..2d363d1f6e 100644 --- a/src/EFCore.PG.NTS/Infrastructure/Internal/NpgsqlNetTopologySuiteOptionsExtension.cs +++ b/src/EFCore.PG.NTS/Infrastructure/Internal/NpgsqlNetTopologySuiteOptionsExtension.cs @@ -15,7 +15,7 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal { public class NpgsqlNetTopologySuiteOptionsExtension : IDbContextOptionsExtension { - DbContextOptionsExtensionInfo _info; + DbContextOptionsExtensionInfo? _info; public virtual bool IsGeographyDefault { get; private set; } @@ -61,7 +61,7 @@ public virtual void Validate(IDbContextOptions options) sealed class ExtensionInfo : DbContextOptionsExtensionInfo { - string _logFragment; + string? _logFragment; public ExtensionInfo(IDbContextOptionsExtension extension) : base(extension) diff --git a/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMemberTranslatorPlugin.cs b/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMemberTranslatorPlugin.cs index 0030c64486..96ee401efd 100644 --- a/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMemberTranslatorPlugin.cs +++ b/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMemberTranslatorPlugin.cs @@ -66,23 +66,20 @@ public NpgsqlGeometryMemberTranslator( }; } - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MemberInfo member, Type returnType, IDiagnosticsLogger logger) { var declaringType = member.DeclaringType; - if (!typeof(Geometry).IsAssignableFrom(declaringType)) + if (instance is null || !typeof(Geometry).IsAssignableFrom(declaringType)) return null; var typeMapping = instance.TypeMapping; Debug.Assert(typeMapping != null, "Instance must have typeMapping assigned."); - var storeType = instance.TypeMapping.StoreType; - var resultGeometryTypeMapping = typeof(Geometry).IsAssignableFrom(returnType) - ? _typeMappingSource.FindMapping(returnType, storeType) - : null; + var storeType = instance.TypeMapping!.StoreType; if (typeof(Point).IsAssignableFrom(declaringType)) { @@ -108,13 +105,13 @@ public virtual SqlExpression Translate( return member.Name switch { nameof(Geometry.Area) => Function("ST_Area", new[] { instance }, typeof(double)), - nameof(Geometry.Boundary) => Function("ST_Boundary", new[] { instance }, typeof(Geometry), resultGeometryTypeMapping), - nameof(Geometry.Centroid) => Function("ST_Centroid", new[] { instance }, typeof(Point), resultGeometryTypeMapping), + nameof(Geometry.Boundary) => Function("ST_Boundary", new[] { instance }, typeof(Geometry), ResultGeometryMapping()), + nameof(Geometry.Centroid) => Function("ST_Centroid", new[] { instance }, typeof(Point), ResultGeometryMapping()), nameof(GeometryCollection.Count) => Function("ST_NumGeometries", new[] { instance }, typeof(int)), nameof(Geometry.Dimension) => Function("ST_Dimension", new[] { instance }, typeof(Dimension)), - nameof(LineString.EndPoint) => Function("ST_EndPoint", new[] { instance }, typeof(Point), resultGeometryTypeMapping), - nameof(Geometry.Envelope) => Function("ST_Envelope", new[] { instance }, typeof(Geometry), resultGeometryTypeMapping), - nameof(Polygon.ExteriorRing) => Function("ST_ExteriorRing", new[] { instance }, typeof(LineString), resultGeometryTypeMapping), + nameof(LineString.EndPoint) => Function("ST_EndPoint", new[] { instance }, typeof(Point), ResultGeometryMapping()), + nameof(Geometry.Envelope) => Function("ST_Envelope", new[] { instance }, typeof(Geometry), ResultGeometryMapping()), + nameof(Polygon.ExteriorRing) => Function("ST_ExteriorRing", new[] { instance }, typeof(LineString), ResultGeometryMapping()), nameof(Geometry.GeometryType) => Function("GeometryType", new[] { instance }, typeof(string)), nameof(LineString.IsClosed) => Function("ST_IsClosed", new[] { instance }, typeof(bool)), nameof(Geometry.IsEmpty) => Function("ST_IsEmpty", new[] { instance }, typeof(bool)), @@ -125,10 +122,10 @@ public virtual SqlExpression Translate( nameof(Geometry.NumGeometries) => Function("ST_NumGeometries", new[] { instance }, typeof(int)), nameof(Polygon.NumInteriorRings) => Function("ST_NumInteriorRings", new[] { instance }, typeof(int)), nameof(Geometry.NumPoints) => Function("ST_NumPoints", new[] { instance }, typeof(int)), - nameof(Geometry.PointOnSurface) => Function("ST_PointOnSurface", new[] { instance }, typeof(Geometry), resultGeometryTypeMapping), - nameof(Geometry.InteriorPoint) => Function("ST_PointOnSurface", new[] { instance }, typeof(Geometry), resultGeometryTypeMapping), + nameof(Geometry.PointOnSurface) => Function("ST_PointOnSurface", new[] { instance }, typeof(Geometry), ResultGeometryMapping()), + nameof(Geometry.InteriorPoint) => Function("ST_PointOnSurface", new[] { instance }, typeof(Geometry), ResultGeometryMapping()), nameof(Geometry.SRID) => Function("ST_SRID", new[] { instance }, typeof(int)), - nameof(LineString.StartPoint) => Function("ST_StartPoint", new[] { instance }, typeof(Point), resultGeometryTypeMapping), + nameof(LineString.StartPoint) => Function("ST_StartPoint", new[] { instance }, typeof(Point), ResultGeometryMapping()), nameof(Geometry.OgcGeometryType) => _sqlExpressionFactory.Case( Function("ST_GeometryType", new[] { instance }, typeof(string)), @@ -138,10 +135,16 @@ public virtual SqlExpression Translate( _ => null }; - SqlFunctionExpression Function(string name, SqlExpression[] arguments, Type returnType, RelationalTypeMapping typeMapping = null) + SqlFunctionExpression Function(string name, SqlExpression[] arguments, Type returnType, RelationalTypeMapping? typeMapping = null) => _sqlExpressionFactory.Function(name, arguments, nullable: true, argumentsPropagateNullability: TrueArrays[arguments.Length], returnType, typeMapping); + + RelationalTypeMapping ResultGeometryMapping() + { + Debug.Assert(typeof(Geometry).IsAssignableFrom(returnType)); + return _typeMappingSource.FindMapping(returnType, storeType)!; + } } } } diff --git a/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs b/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs index 6d9b094cd3..f2f41a5596 100644 --- a/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs +++ b/src/EFCore.PG.NTS/Query/ExpressionTranslators/Internal/NpgsqlNetTopologySuiteMethodCallTranslatorPlugin.cs @@ -32,8 +32,7 @@ public NpgsqlNetTopologySuiteMethodCallTranslatorPlugin( /// public class NpgsqlGeometryMethodTranslator : IMethodCallTranslator { - static readonly MethodInfo _collectionItem = - typeof(GeometryCollection).GetRuntimeProperty("Item").GetMethod; + static readonly MethodInfo _collectionItem = typeof(GeometryCollection).GetRuntimeProperty("Item")!.GetMethod!; readonly ISqlExpressionFactory _sqlExpressionFactory; readonly IRelationalTypeMappingSource _typeMappingSource; @@ -56,19 +55,18 @@ public NpgsqlGeometryMethodTranslator( } /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) - => typeof(Geometry).IsAssignableFrom(method.DeclaringType) - ? TranslateGeometryMethod(instance, method, arguments) - : method.DeclaringType == typeof(NpgsqlNetTopologySuiteDbFunctionsExtensions) - ? TranslateDbFunction(instance, method, arguments) + => method.DeclaringType == typeof(NpgsqlNetTopologySuiteDbFunctionsExtensions) + ? TranslateDbFunction(method, arguments) + : instance is not null && typeof(Geometry).IsAssignableFrom(method.DeclaringType) + ? TranslateGeometryMethod(instance, method, arguments) : null; - protected virtual SqlExpression TranslateDbFunction( - [CanBeNull] SqlExpression instance, + private SqlExpression? TranslateDbFunction( [NotNull] MethodInfo method, [NotNull] IReadOnlyList arguments) => method.Name switch @@ -89,8 +87,8 @@ protected virtual SqlExpression TranslateDbFunction( _ => null }; - protected virtual SqlExpression TranslateGeometryMethod( - [CanBeNull] SqlExpression instance, + private SqlExpression? TranslateGeometryMethod( + [NotNull] SqlExpression instance, [NotNull] MethodInfo method, [NotNull] IReadOnlyList arguments) { @@ -99,9 +97,6 @@ protected virtual SqlExpression TranslateGeometryMethod( Debug.Assert(typeMapping != null, "At least one argument must have typeMapping."); var storeType = typeMapping.StoreType; - var resultGeometryTypeMapping = typeof(Geometry).IsAssignableFrom(method.ReturnType) - ? _typeMappingSource.FindMapping(method.ReturnType, storeType) - : null; instance = _sqlExpressionFactory.ApplyTypeMapping(instance, _typeMappingSource.FindMapping(instance.Type, storeType)); @@ -125,47 +120,47 @@ protected virtual SqlExpression TranslateGeometryMethod( nullable: true, argumentsPropagateNullability: TrueArrays[2], method.ReturnType, - _typeMappingSource.FindMapping(typeof(Geometry), instance.TypeMapping.StoreType)); + _typeMappingSource.FindMapping(typeof(Geometry), instance.TypeMapping!.StoreType)); } return method.Name switch { nameof(Geometry.AsBinary) => Function("ST_AsBinary", new[] { instance }, typeof(byte[])), nameof(Geometry.AsText) => Function("ST_AsText", new[] { instance }, typeof(string)), - nameof(Geometry.Buffer) => Function("ST_Buffer", new[] { instance }.Concat(arguments).ToArray(), typeof(Geometry), resultGeometryTypeMapping), + nameof(Geometry.Buffer) => Function("ST_Buffer", new[] { instance }.Concat(arguments).ToArray(), typeof(Geometry), ResultGeometryMapping()), nameof(Geometry.Contains) => Function("ST_Contains", new[] { instance, arguments[0] }, typeof(bool)), - nameof(Geometry.ConvexHull) => Function("ST_ConvexHull", new[] { instance }, typeof(Geometry), resultGeometryTypeMapping), + nameof(Geometry.ConvexHull) => Function("ST_ConvexHull", new[] { instance }, typeof(Geometry), ResultGeometryMapping()), nameof(Geometry.CoveredBy) => Function("ST_CoveredBy", new[] { instance, arguments[0] }, typeof(bool)), nameof(Geometry.Covers) => Function("ST_Covers", new[] { instance, arguments[0] }, typeof(bool)), nameof(Geometry.Crosses) => Function("ST_Crosses", new[] { instance, arguments[0] }, typeof(bool)), nameof(Geometry.Disjoint) => Function("ST_Disjoint", new[] { instance, arguments[0] }, typeof(bool)), - nameof(Geometry.Difference) => Function("ST_Difference", new[] { instance, arguments[0] }, typeof(Geometry), resultGeometryTypeMapping), + nameof(Geometry.Difference) => Function("ST_Difference", new[] { instance, arguments[0] }, typeof(Geometry), ResultGeometryMapping()), nameof(Geometry.Distance) => Function("ST_Distance", new[] { instance }.Concat(arguments).ToArray(), typeof(double)), nameof(Geometry.EqualsExact) => Function("ST_OrderingEquals", new[] { instance, arguments[0] }, typeof(bool)), nameof(Geometry.EqualsTopologically) => Function("ST_Equals", new[] { instance, arguments[0] }, typeof(bool)), - nameof(Geometry.GetGeometryN) => Function("ST_GeometryN", new[] { instance, OneBased(arguments[0]) }, typeof(Geometry), resultGeometryTypeMapping), - nameof(Polygon.GetInteriorRingN) => Function("ST_InteriorRingN", new[] { instance, OneBased(arguments[0]) }, typeof(Geometry), resultGeometryTypeMapping), - nameof(LineString.GetPointN) => Function("ST_PointN", new[] { instance, OneBased(arguments[0]) }, typeof(Geometry), resultGeometryTypeMapping), - nameof(Geometry.Intersection) => Function("ST_Intersection", new[] { instance, arguments[0] }, typeof(Geometry), resultGeometryTypeMapping), + nameof(Geometry.GetGeometryN) => Function("ST_GeometryN", new[] { instance, OneBased(arguments[0]) }, typeof(Geometry), ResultGeometryMapping()), + nameof(Polygon.GetInteriorRingN) => Function("ST_InteriorRingN", new[] { instance, OneBased(arguments[0]) }, typeof(Geometry), ResultGeometryMapping()), + nameof(LineString.GetPointN) => Function("ST_PointN", new[] { instance, OneBased(arguments[0]) }, typeof(Geometry), ResultGeometryMapping()), + nameof(Geometry.Intersection) => Function("ST_Intersection", new[] { instance, arguments[0] }, typeof(Geometry), ResultGeometryMapping()), nameof(Geometry.Intersects) => Function("ST_Intersects", new[] { instance, arguments[0] }, typeof(bool)), nameof(Geometry.IsWithinDistance) => Function("ST_DWithin", new[] { instance }.Concat(arguments).ToArray(), typeof(bool)), - nameof(Geometry.Normalized) => Function("ST_Normalize", new[] { instance }, typeof(Geometry), resultGeometryTypeMapping), + nameof(Geometry.Normalized) => Function("ST_Normalize", new[] { instance }, typeof(Geometry), ResultGeometryMapping()), nameof(Geometry.Overlaps) => Function("ST_Overlaps", new[] { instance, arguments[0] }, typeof(bool)), nameof(Geometry.Relate) => Function("ST_Relate", new[] { instance, arguments[0], arguments[1] }, typeof(bool)), - nameof(Geometry.Reverse) => Function("ST_Reverse", new[] { instance }, typeof(Geometry), resultGeometryTypeMapping), - nameof(Geometry.SymmetricDifference) => Function("ST_SymDifference", new[] { instance, arguments[0] }, typeof(Geometry), resultGeometryTypeMapping), + nameof(Geometry.Reverse) => Function("ST_Reverse", new[] { instance }, typeof(Geometry), ResultGeometryMapping()), + nameof(Geometry.SymmetricDifference) => Function("ST_SymDifference", new[] { instance, arguments[0] }, typeof(Geometry), ResultGeometryMapping()), nameof(Geometry.ToBinary) => Function("ST_AsBinary", new[] { instance }, typeof(byte[])), nameof(Geometry.ToText) => Function("ST_AsText", new[] { instance }, typeof(string)), nameof(Geometry.Touches) => Function("ST_Touches", new[] { instance, arguments[0] }, typeof(bool)), nameof(Geometry.Within) => Function("ST_Within", new[] { instance, arguments[0] }, typeof(bool)), - nameof(Geometry.Union) when arguments.Count == 0 => Function("ST_UnaryUnion", new[] { instance }, typeof(Geometry), resultGeometryTypeMapping), - nameof(Geometry.Union) when arguments.Count == 1 => Function("ST_Union", new[] { instance, arguments[0] }, typeof(Geometry), resultGeometryTypeMapping), + nameof(Geometry.Union) when arguments.Count == 0 => Function("ST_UnaryUnion", new[] { instance }, typeof(Geometry), ResultGeometryMapping()), + nameof(Geometry.Union) when arguments.Count == 1 => Function("ST_Union", new[] { instance, arguments[0] }, typeof(Geometry), ResultGeometryMapping()), _ => null }; - SqlFunctionExpression Function(string name, SqlExpression[] arguments, Type returnType, RelationalTypeMapping typeMapping = null) + SqlFunctionExpression Function(string name, SqlExpression[] arguments, Type returnType, RelationalTypeMapping? typeMapping = null) => _sqlExpressionFactory.Function(name, arguments, nullable: true, argumentsPropagateNullability: TrueArrays[arguments.Length], returnType, typeMapping); @@ -173,8 +168,14 @@ SqlFunctionExpression Function(string name, SqlExpression[] arguments, Type retu // NetTopologySuite uses 0-based indexing, but PostGIS uses 1-based SqlExpression OneBased(SqlExpression arg) => arg is SqlConstantExpression constant - ? _sqlExpressionFactory.Constant((int)constant.Value + 1, constant.TypeMapping) + ? _sqlExpressionFactory.Constant((int)constant.Value! + 1, constant.TypeMapping) : (SqlExpression)_sqlExpressionFactory.Add(arg, _sqlExpressionFactory.Constant(1)); + + RelationalTypeMapping ResultGeometryMapping() + { + Debug.Assert(typeof(Geometry).IsAssignableFrom(method.ReturnType)); + return _typeMappingSource.FindMapping(method.ReturnType, storeType)!; + } } } } diff --git a/src/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs b/src/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs index 4b8b0e40f3..4dbb2042d9 100644 --- a/src/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs +++ b/src/EFCore.PG.NTS/Storage/Internal/NpgsqlNetTopologySuiteTypeMappingSourcePlugin.cs @@ -4,6 +4,7 @@ using NetTopologySuite.Geometries; using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal; using Npgsql.EntityFrameworkCore.PostgreSQL.Utilities; +using CA = System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal @@ -14,7 +15,7 @@ public class NpgsqlNetTopologySuiteTypeMappingSourcePlugin : IRelationalTypeMapp // rather late by SingletonOptionsInitializer readonly INpgsqlNetTopologySuiteOptions _options; - static bool TryGetClrType(string subtypeName, out Type clrType) + static bool TryGetClrType(string subtypeName, [CA.NotNullWhen(true)] out Type? clrType) { clrType = subtypeName switch { @@ -35,7 +36,7 @@ static bool TryGetClrType(string subtypeName, out Type clrType) public NpgsqlNetTopologySuiteTypeMappingSourcePlugin([NotNull] INpgsqlNetTopologySuiteOptions options) => _options = Check.NotNull(options, nameof(options)); - public virtual RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo) + public virtual RelationalTypeMapping? FindMapping(in RelationalTypeMappingInfo mappingInfo) { // TODO: Array var clrType = mappingInfo.ClrType; @@ -57,7 +58,7 @@ public virtual RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo ma ? (RelationalTypeMapping)Activator.CreateInstance( typeof(NpgsqlGeometryTypeMapping<>).MakeGenericType(clrType ?? typeof(Geometry)), storeTypeName ?? (isGeography ? "geography" : "geometry"), - isGeography) + isGeography)! : null; } @@ -69,7 +70,7 @@ public static bool TryParseStoreTypeName( [NotNull] string storeTypeName, out string subtypeName, out bool isGeography, - out Type clrType, + out Type? clrType, out int srid, out Ordinates ordinates) { diff --git a/src/EFCore.PG.NodaTime/Extensions/TypeExtensions.cs b/src/EFCore.PG.NodaTime/Extensions/TypeExtensions.cs index a30f1ad04e..60d09b2993 100644 --- a/src/EFCore.PG.NodaTime/Extensions/TypeExtensions.cs +++ b/src/EFCore.PG.NodaTime/Extensions/TypeExtensions.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; -#nullable enable - // ReSharper disable once CheckNamespace namespace Npgsql.EntityFrameworkCore.PostgreSQL { diff --git a/src/EFCore.PG.NodaTime/Infrastructure/Internal/NpgsqlNodaTimeOptionsExtension.cs b/src/EFCore.PG.NodaTime/Infrastructure/Internal/NpgsqlNodaTimeOptionsExtension.cs index c5a6a52941..556e267ee2 100644 --- a/src/EFCore.PG.NodaTime/Infrastructure/Internal/NpgsqlNodaTimeOptionsExtension.cs +++ b/src/EFCore.PG.NodaTime/Infrastructure/Internal/NpgsqlNodaTimeOptionsExtension.cs @@ -12,7 +12,7 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal { public class NpgsqlNodaTimeOptionsExtension : IDbContextOptionsExtension { - DbContextOptionsExtensionInfo _info; + DbContextOptionsExtensionInfo? _info; public virtual void ApplyServices(IServiceCollection services) => services.AddEntityFrameworkNpgsqlNodaTime(); diff --git a/src/EFCore.PG.NodaTime/Query/ExpressionTranslators/Internal/NpgsqlNodaTimeMemberTranslatorPlugin.cs b/src/EFCore.PG.NodaTime/Query/ExpressionTranslators/Internal/NpgsqlNodaTimeMemberTranslatorPlugin.cs index 7d51a07db2..c87352ba27 100644 --- a/src/EFCore.PG.NodaTime/Query/ExpressionTranslators/Internal/NpgsqlNodaTimeMemberTranslatorPlugin.cs +++ b/src/EFCore.PG.NodaTime/Query/ExpressionTranslators/Internal/NpgsqlNodaTimeMemberTranslatorPlugin.cs @@ -44,7 +44,7 @@ public class NpgsqlNodaTimeMemberTranslator : IMemberTranslator /// The static member info for . /// [NotNull] static readonly MemberInfo Instance = - typeof(SystemClock).GetRuntimeProperty(nameof(SystemClock.Instance)); + typeof(SystemClock).GetRuntimeProperty(nameof(SystemClock.Instance))!; public NpgsqlNodaTimeMemberTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory) => _sqlExpressionFactory = sqlExpressionFactory; @@ -57,8 +57,8 @@ public NpgsqlNodaTimeMemberTranslator([NotNull] ISqlExpressionFactory sqlExpress }; /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MemberInfo member, Type returnType, IDiagnosticsLogger logger) @@ -68,10 +68,11 @@ public virtual SqlExpression Translate( return _sqlExpressionFactory.Constant(SystemClock.Instance); var declaringType = member.DeclaringType; - if (declaringType == typeof(LocalDateTime) || - declaringType == typeof(LocalDate) || - declaringType == typeof(LocalTime) || - declaringType == typeof(Period)) + if (instance is not null + && (declaringType == typeof(LocalDateTime) + || declaringType == typeof(LocalDate) + || declaringType == typeof(LocalTime) + || declaringType == typeof(Period))) { return TranslateDateTime(instance, member, returnType); } @@ -87,7 +88,7 @@ public virtual SqlExpression Translate( /// The translated expression or null. /// [CanBeNull] - SqlExpression TranslateDateTime(SqlExpression instance, MemberInfo member, Type returnType) + SqlExpression? TranslateDateTime(SqlExpression instance, MemberInfo member, Type returnType) { switch (member.Name) { diff --git a/src/EFCore.PG.NodaTime/Query/ExpressionTranslators/Internal/NpgsqlNodaTimeMethodCallTranslatorPlugin.cs b/src/EFCore.PG.NodaTime/Query/ExpressionTranslators/Internal/NpgsqlNodaTimeMethodCallTranslatorPlugin.cs index f07368bfa0..9c0749e05b 100644 --- a/src/EFCore.PG.NodaTime/Query/ExpressionTranslators/Internal/NpgsqlNodaTimeMethodCallTranslatorPlugin.cs +++ b/src/EFCore.PG.NodaTime/Query/ExpressionTranslators/Internal/NpgsqlNodaTimeMethodCallTranslatorPlugin.cs @@ -43,20 +43,20 @@ public class NpgsqlNodaTimeMethodCallTranslator : IMethodCallTranslator /// The static method info for . /// [NotNull] static readonly MethodInfo GetCurrentInstant = - typeof(SystemClock).GetRuntimeMethod(nameof(SystemClock.GetCurrentInstant), Type.EmptyTypes); + typeof(SystemClock).GetRuntimeMethod(nameof(SystemClock.GetCurrentInstant), Type.EmptyTypes)!; /// /// The mapping of supported method translations. /// [NotNull] static readonly Dictionary PeriodMethodMap = new() { - { typeof(Period).GetRuntimeMethod(nameof(Period.FromYears), new[] { typeof(int) }), "years" }, - { typeof(Period).GetRuntimeMethod(nameof(Period.FromMonths), new[] { typeof(int) }), "months" }, - { typeof(Period).GetRuntimeMethod(nameof(Period.FromWeeks), new[] { typeof(int) }), "weeks" }, - { typeof(Period).GetRuntimeMethod(nameof(Period.FromDays), new[] { typeof(int) }), "days" }, - { typeof(Period).GetRuntimeMethod(nameof(Period.FromHours), new[] { typeof(long) }), "hours" }, - { typeof(Period).GetRuntimeMethod(nameof(Period.FromMinutes), new[] { typeof(long) }), "mins" }, - { typeof(Period).GetRuntimeMethod(nameof(Period.FromSeconds), new[] { typeof(long) }), "secs" }, + { typeof(Period).GetRuntimeMethod(nameof(Period.FromYears), new[] { typeof(int) })!, "years" }, + { typeof(Period).GetRuntimeMethod(nameof(Period.FromMonths), new[] { typeof(int) })!, "months" }, + { typeof(Period).GetRuntimeMethod(nameof(Period.FromWeeks), new[] { typeof(int) })!, "weeks" }, + { typeof(Period).GetRuntimeMethod(nameof(Period.FromDays), new[] { typeof(int) })!, "days" }, + { typeof(Period).GetRuntimeMethod(nameof(Period.FromHours), new[] { typeof(long) })!, "hours" }, + { typeof(Period).GetRuntimeMethod(nameof(Period.FromMinutes), new[] { typeof(long) })!, "mins" }, + { typeof(Period).GetRuntimeMethod(nameof(Period.FromSeconds), new[] { typeof(long) })!, "secs" }, //{ typeof(Period).GetRuntimeMethod(nameof(Period.FromMilliseconds), new[] { typeof(long) }), "" }, //{ typeof(Period).GetRuntimeMethod(nameof(Period.FromNanoseconds), new[] { typeof(long) }), "" }, }; @@ -73,8 +73,8 @@ public NpgsqlNodaTimeMethodCallTranslator([NotNull] NpgsqlSqlExpressionFactory s #pragma warning disable EF1001 /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) diff --git a/src/EFCore.PG.NodaTime/Query/Internal/NpgsqlNodaTimeEvaluatableExpressionFilterPlugin.cs b/src/EFCore.PG.NodaTime/Query/Internal/NpgsqlNodaTimeEvaluatableExpressionFilterPlugin.cs index 469837baef..48f10599a3 100644 --- a/src/EFCore.PG.NodaTime/Query/Internal/NpgsqlNodaTimeEvaluatableExpressionFilterPlugin.cs +++ b/src/EFCore.PG.NodaTime/Query/Internal/NpgsqlNodaTimeEvaluatableExpressionFilterPlugin.cs @@ -10,10 +10,10 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.NodaTime.Query.Internal public class NpgsqlNodaTimeEvaluatableExpressionFilterPlugin : IEvaluatableExpressionFilterPlugin { static readonly MethodInfo GetCurrentInstantMethod = - typeof(SystemClock).GetRuntimeMethod(nameof(SystemClock.GetCurrentInstant), Array.Empty()); + typeof(SystemClock).GetRuntimeMethod(nameof(SystemClock.GetCurrentInstant), Array.Empty())!; static readonly MemberInfo SystemClockInstanceMember = - typeof(SystemClock).GetMember(nameof(SystemClock.Instance)).FirstOrDefault(); + typeof(SystemClock).GetMember(nameof(SystemClock.Instance)).FirstOrDefault()!; public virtual bool IsEvaluatableExpression(Expression expression) => !( diff --git a/src/EFCore.PG.NodaTime/Storage/Internal/NodaTimeMappings.cs b/src/EFCore.PG.NodaTime/Storage/Internal/NodaTimeMappings.cs index 0f0f69b2c7..19a1712db6 100644 --- a/src/EFCore.PG.NodaTime/Storage/Internal/NodaTimeMappings.cs +++ b/src/EFCore.PG.NodaTime/Storage/Internal/NodaTimeMappings.cs @@ -1,4 +1,3 @@ -using System; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using NodaTime; @@ -28,7 +27,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p public override RelationalTypeMapping Clone(string storeType, int? size) => new TimestampInstantMapping(Parameters.WithStoreTypeAndSize(storeType, size)); - public override CoreTypeMapping Clone(ValueConverter converter) + public override CoreTypeMapping Clone(ValueConverter? converter) => new TimestampInstantMapping(Parameters.WithComposedConverter(converter)); protected override string GenerateNonNullSqlLiteral(object value) @@ -41,19 +40,19 @@ internal static Expression GenerateCodeLiteral(Instant instant) => Expression.Call(FromUnixTimeTicks, Expression.Constant(instant.ToUnixTimeTicks())); static readonly MethodInfo FromUnixTimeTicks - = typeof(Instant).GetRuntimeMethod(nameof(Instant.FromUnixTimeTicks), new[] { typeof(long) }); + = typeof(Instant).GetRuntimeMethod(nameof(Instant.FromUnixTimeTicks), new[] { typeof(long) })!; } public class TimestampLocalDateTimeMapping : NpgsqlTypeMapping { static readonly ConstructorInfo ConstructorWithMinutes = - typeof(LocalDateTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); + typeof(LocalDateTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) })!; static readonly ConstructorInfo ConstructorWithSeconds = - typeof(LocalDateTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); + typeof(LocalDateTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) })!; static readonly MethodInfo PlusNanosecondsMethod = - typeof(LocalDateTime).GetMethod(nameof(LocalDateTime.PlusNanoseconds), new[] { typeof(long) }); + typeof(LocalDateTime).GetMethod(nameof(LocalDateTime.PlusNanoseconds), new[] { typeof(long) })!; public TimestampLocalDateTimeMapping() : base("timestamp", typeof(LocalDateTime), NpgsqlDbType.Timestamp) {} @@ -66,7 +65,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p public override RelationalTypeMapping Clone(string storeType, int? size) => new TimestampLocalDateTimeMapping(Parameters.WithStoreTypeAndSize(storeType, size)); - public override CoreTypeMapping Clone(ValueConverter converter) + public override CoreTypeMapping Clone(ValueConverter? converter) => new TimestampLocalDateTimeMapping(Parameters.WithComposedConverter(converter)); protected override string GenerateNonNullSqlLiteral(object value) @@ -104,7 +103,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p public override RelationalTypeMapping Clone(string storeType, int? size) => new TimestampTzInstantMapping(Parameters.WithStoreTypeAndSize(storeType, size)); - public override CoreTypeMapping Clone(ValueConverter converter) + public override CoreTypeMapping Clone(ValueConverter? converter) => new TimestampTzInstantMapping(Parameters.WithComposedConverter(converter)); protected override string GenerateNonNullSqlLiteral(object value) @@ -117,13 +116,13 @@ public override Expression GenerateCodeLiteral(object value) public class TimestampTzOffsetDateTimeMapping : NpgsqlTypeMapping { static readonly ConstructorInfo Constructor = - typeof(OffsetDateTime).GetConstructor(new[] { typeof(LocalDateTime), typeof(Offset) }); + typeof(OffsetDateTime).GetConstructor(new[] { typeof(LocalDateTime), typeof(Offset) })!; static readonly MethodInfo OffsetFromHoursMethod = - typeof(Offset).GetMethod(nameof(Offset.FromHours), new[] { typeof(int) }); + typeof(Offset).GetMethod(nameof(Offset.FromHours), new[] { typeof(int) })!; static readonly MethodInfo OffsetFromSecondsMethod = - typeof(Offset).GetMethod(nameof(Offset.FromSeconds), new[] { typeof(int) }); + typeof(Offset).GetMethod(nameof(Offset.FromSeconds), new[] { typeof(int) })!; public TimestampTzOffsetDateTimeMapping() : base("timestamp with time zone", typeof(OffsetDateTime), NpgsqlDbType.TimestampTz) {} @@ -136,7 +135,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p public override RelationalTypeMapping Clone(string storeType, int? size) => new TimestampTzOffsetDateTimeMapping(Parameters.WithStoreTypeAndSize(storeType, size)); - public override CoreTypeMapping Clone(ValueConverter converter) + public override CoreTypeMapping Clone(ValueConverter? converter) => new TimestampTzOffsetDateTimeMapping(Parameters.WithComposedConverter(converter)); protected override string GenerateNonNullSqlLiteral(object value) @@ -172,7 +171,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p public override RelationalTypeMapping Clone(string storeType, int? size) => new TimestampTzZonedDateTimeMapping(Parameters.WithStoreTypeAndSize(storeType, size)); - public override CoreTypeMapping Clone(ValueConverter converter) + public override CoreTypeMapping Clone(ValueConverter? converter) => new TimestampTzZonedDateTimeMapping(Parameters.WithComposedConverter(converter)); protected override string GenerateNonNullSqlLiteral(object value) @@ -194,7 +193,7 @@ public override Expression GenerateCodeLiteral(object value) } static readonly ConstructorInfo Constructor = - typeof(ZonedDateTime).GetConstructor(new[] { typeof(Instant), typeof(DateTimeZone) }); + typeof(ZonedDateTime).GetConstructor(new[] { typeof(Instant), typeof(DateTimeZone) })!; static readonly MemberInfo TzdbDateTimeZoneSourceDefaultMember = typeof(TzdbDateTimeZoneSource).GetMember(nameof(TzdbDateTimeZoneSource.Default))[0]; @@ -202,7 +201,7 @@ public override Expression GenerateCodeLiteral(object value) static readonly MethodInfo ForIdMethod = typeof(TzdbDateTimeZoneSource).GetRuntimeMethod( nameof(TzdbDateTimeZoneSource.ForId), - new[] { typeof(string) }); + new[] { typeof(string) })!; } #endregion timestamptz @@ -212,7 +211,7 @@ public override Expression GenerateCodeLiteral(object value) public class DateMapping : NpgsqlTypeMapping { static readonly ConstructorInfo Constructor = - typeof(LocalDate).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) }); + typeof(LocalDate).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) })!; public DateMapping() : base("date", typeof(LocalDate), NpgsqlDbType.Date) {} @@ -225,7 +224,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p public override RelationalTypeMapping Clone(string storeType, int? size) => new DateMapping(Parameters.WithStoreTypeAndSize(storeType, size)); - public override CoreTypeMapping Clone(ValueConverter converter) + public override CoreTypeMapping Clone(ValueConverter? converter) => new DateMapping(Parameters.WithComposedConverter(converter)); protected override string GenerateNonNullSqlLiteral(object value) @@ -245,14 +244,14 @@ public override Expression GenerateCodeLiteral(object value) public class TimeMapping : NpgsqlTypeMapping { static readonly ConstructorInfo ConstructorWithMinutes = - typeof(LocalTime).GetConstructor(new[] { typeof(int), typeof(int) }); + typeof(LocalTime).GetConstructor(new[] { typeof(int), typeof(int) })!; static readonly ConstructorInfo ConstructorWithSeconds = - typeof(LocalTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) }); + typeof(LocalTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) })!; static readonly MethodInfo FromHourMinuteSecondNanosecondMethod = typeof(LocalTime).GetMethod(nameof(LocalTime.FromHourMinuteSecondNanosecond), - new[] { typeof(int), typeof(int), typeof(int), typeof(long) }); + new[] { typeof(int), typeof(int), typeof(int), typeof(long) })!; public TimeMapping() : base("time", typeof(LocalTime), NpgsqlDbType.Time) {} @@ -265,7 +264,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p public override RelationalTypeMapping Clone(string storeType, int? size) => new TimeMapping(Parameters.WithStoreTypeAndSize(storeType, size)); - public override CoreTypeMapping Clone(ValueConverter converter) + public override CoreTypeMapping Clone(ValueConverter? converter) => new TimeMapping(Parameters.WithComposedConverter(converter)); protected override string GenerateNonNullSqlLiteral(object value) @@ -289,23 +288,23 @@ public override Expression GenerateCodeLiteral(object value) public class TimeTzMapping : NpgsqlTypeMapping { static readonly ConstructorInfo OffsetTimeConstructor = - typeof(OffsetTime).GetConstructor(new[] { typeof(LocalTime), typeof(Offset) }); + typeof(OffsetTime).GetConstructor(new[] { typeof(LocalTime), typeof(Offset) })!; static readonly ConstructorInfo LocalTimeConstructorWithMinutes = - typeof(LocalTime).GetConstructor(new[] { typeof(int), typeof(int) }); + typeof(LocalTime).GetConstructor(new[] { typeof(int), typeof(int) })!; static readonly ConstructorInfo LocalTimeConstructorWithSeconds = - typeof(LocalTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) }); + typeof(LocalTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) })!; static readonly MethodInfo LocalTimeFromHourMinuteSecondNanosecondMethod = typeof(LocalTime).GetMethod(nameof(LocalTime.FromHourMinuteSecondNanosecond), - new[] { typeof(int), typeof(int), typeof(int), typeof(long) }); + new[] { typeof(int), typeof(int), typeof(int), typeof(long) })!; static readonly MethodInfo OffsetFromHoursMethod = - typeof(Offset).GetMethod(nameof(Offset.FromHours), new[] { typeof(int) }); + typeof(Offset).GetMethod(nameof(Offset.FromHours), new[] { typeof(int) })!; static readonly MethodInfo OffsetFromSeconds = - typeof(Offset).GetMethod(nameof(Offset.FromSeconds), new[] { typeof(int) }); + typeof(Offset).GetMethod(nameof(Offset.FromSeconds), new[] { typeof(int) })!; static readonly OffsetTimePattern Pattern = OffsetTimePattern.CreateWithInvariantCulture("HH':'mm':'ss;FFFFFFo"); @@ -321,7 +320,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p public override RelationalTypeMapping Clone(string storeType, int? size) => new TimeTzMapping(Parameters.WithStoreTypeAndSize(storeType, size)); - public override CoreTypeMapping Clone(ValueConverter converter) + public override CoreTypeMapping Clone(ValueConverter? converter) => new TimeTzMapping(Parameters.WithComposedConverter(converter)); protected override string GenerateNonNullSqlLiteral(object value) @@ -354,15 +353,17 @@ public override Expression GenerateCodeLiteral(object value) public class PeriodIntervalMapping : NpgsqlTypeMapping { - static readonly MethodInfo FromYears = typeof(Period).GetRuntimeMethod(nameof(Period.FromYears), new[] { typeof(int) }); - static readonly MethodInfo FromMonths = typeof(Period).GetRuntimeMethod(nameof(Period.FromMonths), new[] { typeof(int) }); - static readonly MethodInfo FromWeeks = typeof(Period).GetRuntimeMethod(nameof(Period.FromWeeks), new[] { typeof(int) }); - static readonly MethodInfo FromDays = typeof(Period).GetRuntimeMethod(nameof(Period.FromDays), new[] { typeof(int) }); - static readonly MethodInfo FromHours = typeof(Period).GetRuntimeMethod(nameof(Period.FromHours), new[] { typeof(long) }); - static readonly MethodInfo FromMinutes = typeof(Period).GetRuntimeMethod(nameof(Period.FromMinutes), new[] { typeof(long) }); - static readonly MethodInfo FromSeconds = typeof(Period).GetRuntimeMethod(nameof(Period.FromSeconds), new[] { typeof(long) }); - static readonly MethodInfo FromMilliseconds = typeof(Period).GetRuntimeMethod(nameof(Period.FromMilliseconds), new[] { typeof(long) }); - static readonly MethodInfo FromNanoseconds = typeof(Period).GetRuntimeMethod(nameof(Period.FromNanoseconds), new[] { typeof(long) }); + static readonly MethodInfo FromYears = typeof(Period).GetRuntimeMethod(nameof(Period.FromYears), new[] { typeof(int) })!; + static readonly MethodInfo FromMonths = typeof(Period).GetRuntimeMethod(nameof(Period.FromMonths), new[] { typeof(int) })!; + static readonly MethodInfo FromWeeks = typeof(Period).GetRuntimeMethod(nameof(Period.FromWeeks), new[] { typeof(int) })!; + static readonly MethodInfo FromDays = typeof(Period).GetRuntimeMethod(nameof(Period.FromDays), new[] { typeof(int) })!; + static readonly MethodInfo FromHours = typeof(Period).GetRuntimeMethod(nameof(Period.FromHours), new[] { typeof(long) })!; + static readonly MethodInfo FromMinutes = typeof(Period).GetRuntimeMethod(nameof(Period.FromMinutes), new[] { typeof(long) })!; + static readonly MethodInfo FromSeconds = typeof(Period).GetRuntimeMethod(nameof(Period.FromSeconds), new[] { typeof(long) })!; + static readonly MethodInfo FromMilliseconds = typeof(Period).GetRuntimeMethod(nameof(Period.FromMilliseconds), new[] { typeof(long) })!; + static readonly MethodInfo FromNanoseconds = typeof(Period).GetRuntimeMethod(nameof(Period.FromNanoseconds), new[] { typeof(long) })!; + + private static readonly PropertyInfo Zero = typeof(Period).GetProperty(nameof(Period.Zero))!; public PeriodIntervalMapping() : base("interval", typeof(Period), NpgsqlDbType.Interval) {} @@ -375,7 +376,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p public override RelationalTypeMapping Clone(string storeType, int? size) => new PeriodIntervalMapping(Parameters.WithStoreTypeAndSize(storeType, size)); - public override CoreTypeMapping Clone(ValueConverter converter) + public override CoreTypeMapping Clone(ValueConverter? converter) => new PeriodIntervalMapping(Parameters.WithComposedConverter(converter)); protected override string GenerateNonNullSqlLiteral(object value) @@ -384,7 +385,7 @@ protected override string GenerateNonNullSqlLiteral(object value) public override Expression GenerateCodeLiteral(object value) { var period = (Period)value; - Expression e = null; + Expression? e = null; if (period.Years != 0) Compose(Expression.Call(FromYears, Expression.Constant(period.Years))); @@ -405,7 +406,7 @@ public override Expression GenerateCodeLiteral(object value) if (period.Nanoseconds != 0) Compose(Expression.Call(FromNanoseconds, Expression.Constant(period.Nanoseconds))); - return e; + return e ?? Expression.MakeMemberAccess(null, Zero); void Compose(Expression toAdd) => e = e is null ? toAdd : Expression.Add(e, toAdd); } @@ -413,11 +414,13 @@ public override Expression GenerateCodeLiteral(object value) public class DurationIntervalMapping : NpgsqlTypeMapping { - static readonly MethodInfo FromDays = typeof(Duration).GetRuntimeMethod(nameof(Duration.FromDays), new[] { typeof(int) }); - static readonly MethodInfo FromHours = typeof(Duration).GetRuntimeMethod(nameof(Duration.FromHours), new[] { typeof(int) }); - static readonly MethodInfo FromMinutes = typeof(Duration).GetRuntimeMethod(nameof(Duration.FromMinutes), new[] { typeof(long) }); - static readonly MethodInfo FromSeconds = typeof(Duration).GetRuntimeMethod(nameof(Duration.FromSeconds), new[] { typeof(long) }); - static readonly MethodInfo FromMilliseconds = typeof(Duration).GetRuntimeMethod(nameof(Duration.FromMilliseconds), new[] { typeof(long) }); + static readonly MethodInfo FromDays = typeof(Duration).GetRuntimeMethod(nameof(Duration.FromDays), new[] { typeof(int) })!; + static readonly MethodInfo FromHours = typeof(Duration).GetRuntimeMethod(nameof(Duration.FromHours), new[] { typeof(int) })!; + static readonly MethodInfo FromMinutes = typeof(Duration).GetRuntimeMethod(nameof(Duration.FromMinutes), new[] { typeof(long) })!; + static readonly MethodInfo FromSeconds = typeof(Duration).GetRuntimeMethod(nameof(Duration.FromSeconds), new[] { typeof(long) })!; + static readonly MethodInfo FromMilliseconds = typeof(Duration).GetRuntimeMethod(nameof(Duration.FromMilliseconds), new[] { typeof(long) })!; + + private static readonly PropertyInfo Zero = typeof(Duration).GetProperty(nameof(Duration.Zero))!; public DurationIntervalMapping() : base("interval", typeof(Duration), NpgsqlDbType.Interval) {} @@ -430,7 +433,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p public override RelationalTypeMapping Clone(string storeType, int? size) => new DurationIntervalMapping(Parameters.WithStoreTypeAndSize(storeType, size)); - public override CoreTypeMapping Clone(ValueConverter converter) + public override CoreTypeMapping Clone(ValueConverter? converter) => new DurationIntervalMapping(Parameters.WithComposedConverter(converter)); protected override string GenerateNonNullSqlLiteral(object value) @@ -439,7 +442,7 @@ protected override string GenerateNonNullSqlLiteral(object value) public override Expression GenerateCodeLiteral(object value) { var duration = (Duration)value; - Expression e = null; + Expression? e = null; if (duration.Days != 0) Compose(Expression.Call(FromDays, Expression.Constant(duration.Days))); @@ -452,7 +455,7 @@ public override Expression GenerateCodeLiteral(object value) if (duration.Milliseconds != 0) Compose(Expression.Call(FromMilliseconds, Expression.Constant((long)duration.Milliseconds))); - return e; + return e ?? Expression.MakeMemberAccess(null, Zero); void Compose(Expression toAdd) => e = e is null ? toAdd : Expression.Add(e, toAdd); } diff --git a/src/EFCore.PG.NodaTime/Storage/Internal/NpgsqlNodaTimeTypeMappingSourcePlugin.cs b/src/EFCore.PG.NodaTime/Storage/Internal/NpgsqlNodaTimeTypeMappingSourcePlugin.cs index 6fdbd57a8e..99a3384a0a 100644 --- a/src/EFCore.PG.NodaTime/Storage/Internal/NpgsqlNodaTimeTypeMappingSourcePlugin.cs +++ b/src/EFCore.PG.NodaTime/Storage/Internal/NpgsqlNodaTimeTypeMappingSourcePlugin.cs @@ -93,10 +93,10 @@ public NpgsqlNodaTimeTypeMappingSourcePlugin([NotNull] ISqlGenerationHelper sqlG ClrTypeMappings = new ConcurrentDictionary(clrTypeMappings); } - public virtual RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo) + public virtual RelationalTypeMapping? FindMapping(in RelationalTypeMappingInfo mappingInfo) => FindExistingMapping(mappingInfo) ?? FindArrayMapping(mappingInfo); - protected virtual RelationalTypeMapping FindExistingMapping(in RelationalTypeMappingInfo mappingInfo) + protected virtual RelationalTypeMapping? FindExistingMapping(in RelationalTypeMappingInfo mappingInfo) { var clrType = mappingInfo.ClrType; var storeTypeName = mappingInfo.StoreTypeName; @@ -116,7 +116,7 @@ protected virtual RelationalTypeMapping FindExistingMapping(in RelationalTypeMap return null; } - if (StoreTypeMappings.TryGetValue(storeTypeNameBase, out mappings)) + if (StoreTypeMappings.TryGetValue(storeTypeNameBase!, out mappings)) { if (clrType == null) return mappings[0].Clone(in mappingInfo); @@ -140,10 +140,10 @@ protected virtual RelationalTypeMapping FindExistingMapping(in RelationalTypeMap } // TODO: This is duplicated from NpgsqlTypeMappingSource - protected virtual RelationalTypeMapping FindArrayMapping(in RelationalTypeMappingInfo mappingInfo) + protected virtual RelationalTypeMapping? FindArrayMapping(in RelationalTypeMappingInfo mappingInfo) { var clrType = mappingInfo.ClrType; - Type elementClrType = null; + Type? elementClrType = null; if (clrType != null && !clrType.TryGetElementType(out elementClrType)) return null; // Not an array/list @@ -157,9 +157,9 @@ protected virtual RelationalTypeMapping FindArrayMapping(in RelationalTypeMappin return null; var elementStoreType = storeType.Substring(0, storeType.Length - 2); - var elementStoreTypeNameBase = storeTypeNameBase.Substring(0, storeTypeNameBase.Length - 2); + var elementStoreTypeNameBase = storeTypeNameBase!.Substring(0, storeTypeNameBase.Length - 2); - RelationalTypeMapping elementMapping; + RelationalTypeMapping? elementMapping; if (elementClrType == null) { diff --git a/src/EFCore.PG/Design/Internal/NpgsqlAnnotationCodeGenerator.cs b/src/EFCore.PG/Design/Internal/NpgsqlAnnotationCodeGenerator.cs index 09e218def6..b1230ef8d5 100644 --- a/src/EFCore.PG/Design/Internal/NpgsqlAnnotationCodeGenerator.cs +++ b/src/EFCore.PG/Design/Internal/NpgsqlAnnotationCodeGenerator.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -14,7 +14,7 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Design.Internal { public class NpgsqlAnnotationCodeGenerator : AnnotationCodeGenerator { - public NpgsqlAnnotationCodeGenerator([NotNull] AnnotationCodeGeneratorDependencies dependencies) + public NpgsqlAnnotationCodeGenerator([JetBrains.Annotations.NotNull] AnnotationCodeGeneratorDependencies dependencies) : base(dependencies) {} protected override bool IsHandledByConvention(IModel model, IAnnotation annotation) @@ -23,7 +23,7 @@ protected override bool IsHandledByConvention(IModel model, IAnnotation annotati Check.NotNull(annotation, nameof(annotation)); if (annotation.Name == RelationalAnnotationNames.DefaultSchema - && string.Equals("public", (string)annotation.Value)) + && string.Equals("public", (string?)annotation.Value)) { return true; } @@ -37,7 +37,7 @@ protected override bool IsHandledByConvention(IIndex index, IAnnotation annotati Check.NotNull(annotation, nameof(annotation)); if (annotation.Name == NpgsqlAnnotationNames.IndexMethod - && string.Equals("btree", (string)annotation.Value)) + && string.Equals("btree", (string?)annotation.Value)) { return true; } @@ -58,7 +58,7 @@ protected override bool IsHandledByConvention(IProperty property, IAnnotation an // to assume that the PostgreSQL version of the scaffolded database necessarily determines the // version of the database that the scaffolded model will target. This makes life difficult for // models with mixed strategies but that's an edge case. - return (NpgsqlValueGenerationStrategy)annotation.Value switch + return (NpgsqlValueGenerationStrategy?)annotation.Value switch { NpgsqlValueGenerationStrategy.SerialColumn => true, NpgsqlValueGenerationStrategy.IdentityByDefaultColumn => true, @@ -76,7 +76,7 @@ public override IReadOnlyList GenerateFluentApiCalls( .Concat(GenerateValueGenerationStrategy(annotations, onModel: true)) .ToList(); - protected override MethodCallCodeFragment GenerateFluentApi(IModel model, IAnnotation annotation) + protected override MethodCallCodeFragment? GenerateFluentApi(IModel model, IAnnotation annotation) { Check.NotNull(model, nameof(model)); Check.NotNull(annotation, nameof(annotation)); @@ -131,7 +131,7 @@ protected override MethodCallCodeFragment GenerateFluentApi(IModel model, IAnnot return null; } - protected override MethodCallCodeFragment GenerateFluentApi(IEntityType entityType, IAnnotation annotation) + protected override MethodCallCodeFragment? GenerateFluentApi(IEntityType entityType, IAnnotation annotation) { Check.NotNull(entityType, nameof(entityType)); Check.NotNull(annotation, nameof(annotation)); @@ -187,7 +187,7 @@ IReadOnlyList GenerateValueGenerationStrategy( }; case NpgsqlValueGenerationStrategy.SequenceHiLo: - var name = GetAndRemove(NpgsqlAnnotationNames.HiLoSequenceName); + var name = GetAndRemove(NpgsqlAnnotationNames.HiLoSequenceName)!; var schema = GetAndRemove(NpgsqlAnnotationNames.HiLoSequenceSchema); return new List { @@ -197,7 +197,7 @@ IReadOnlyList GenerateValueGenerationStrategy( { (null, null) => Array.Empty(), (_, null) => new object[] { name }, - _ => new object[] { name, schema } + _ => new object?[] { name!, schema } }) }; @@ -214,8 +214,8 @@ IReadOnlyList GenerateValueGenerationStrategy( throw new ArgumentOutOfRangeException(strategy.ToString()); } - T GetAndRemove(string annotationName) - => TryGetAndRemove(annotations, annotationName, out T annotationValue) + T? GetAndRemove(string annotationName) + => TryGetAndRemove(annotations, annotationName, out T? annotationValue) ? annotationValue : default; } @@ -223,7 +223,7 @@ T GetAndRemove(string annotationName) IReadOnlyList GenerateIdentityOptions(IDictionary annotations) { if (!TryGetAndRemove(annotations, NpgsqlAnnotationNames.IdentityOptions, - out string annotationValue)) + out string? annotationValue)) { return Array.Empty(); } @@ -242,7 +242,7 @@ IReadOnlyList GenerateIdentityOptions(IDictionary annotation.Name switch { RelationalAnnotationNames.Collation @@ -261,7 +261,10 @@ protected override MethodCallCodeFragment GenerateFluentApi(IIndex index, IAnnot _ => null }; - static bool TryGetAndRemove(IDictionary annotations, string annotationName, out T annotationValue) + private static bool TryGetAndRemove( + IDictionary annotations, + string annotationName, + [NotNullWhen(true)] out T? annotationValue) { if (annotations.TryGetValue(annotationName, out var annotation) && annotation.Value != null) diff --git a/src/EFCore.PG/Diagnostics/Internal/NpgsqlLoggingDefinitions.cs b/src/EFCore.PG/Diagnostics/Internal/NpgsqlLoggingDefinitions.cs index 82ea725c24..e21283118c 100644 --- a/src/EFCore.PG/Diagnostics/Internal/NpgsqlLoggingDefinitions.cs +++ b/src/EFCore.PG/Diagnostics/Internal/NpgsqlLoggingDefinitions.cs @@ -4,22 +4,22 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Diagnostics.Internal { public class NpgsqlLoggingDefinitions : RelationalLoggingDefinitions { - public EventDefinitionBase LogFoundDefaultSchema; - public EventDefinitionBase LogFoundColumn; - public EventDefinitionBase LogFoundForeignKey; - public EventDefinitionBase LogFoundCollation; - public EventDefinitionBase LogPrincipalTableNotInSelectionSet; - public EventDefinitionBase LogMissingSchema; - public EventDefinitionBase LogMissingTable; - public EventDefinitionBase LogFoundSequence; - public EventDefinitionBase LogFoundTable; - public EventDefinitionBase LogFoundIndex; - public EventDefinitionBase LogFoundPrimaryKey; - public EventDefinitionBase LogFoundUniqueConstraint; - public EventDefinitionBase LogPrincipalColumnNotFound; - public EventDefinitionBase LogEnumColumnSkipped; - public EventDefinitionBase LogExpressionIndexSkipped; - public EventDefinitionBase LogUnsupportedColumnConstraintSkipped; - public EventDefinitionBase LogUnsupportedColumnIndexSkipped; + public EventDefinitionBase? LogFoundDefaultSchema; + public EventDefinitionBase? LogFoundColumn; + public EventDefinitionBase? LogFoundForeignKey; + public EventDefinitionBase? LogFoundCollation; + public EventDefinitionBase? LogPrincipalTableNotInSelectionSet; + public EventDefinitionBase? LogMissingSchema; + public EventDefinitionBase? LogMissingTable; + public EventDefinitionBase? LogFoundSequence; + public EventDefinitionBase? LogFoundTable; + public EventDefinitionBase? LogFoundIndex; + public EventDefinitionBase? LogFoundPrimaryKey; + public EventDefinitionBase? LogFoundUniqueConstraint; + public EventDefinitionBase? LogPrincipalColumnNotFound; + public EventDefinitionBase? LogEnumColumnSkipped; + public EventDefinitionBase? LogExpressionIndexSkipped; + public EventDefinitionBase? LogUnsupportedColumnConstraintSkipped; + public EventDefinitionBase? LogUnsupportedColumnIndexSkipped; } } diff --git a/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlEntityTypeBuilderExtensions.cs b/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlEntityTypeBuilderExtensions.cs index 4101228e63..87728adb2d 100644 --- a/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlEntityTypeBuilderExtensions.cs +++ b/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlEntityTypeBuilderExtensions.cs @@ -5,6 +5,7 @@ using System.Reflection; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata.Internal; using Npgsql.EntityFrameworkCore.PostgreSQL.Utilities; @@ -158,7 +159,7 @@ public static EntityTypeBuilder HasStorageParameter( /// The value of the storage parameter. /// Indicates whether the configuration was specified using a data annotation. /// The same builder instance so that multiple calls can be chained. - public static IConventionEntityTypeBuilder HasStorageParameter( + public static IConventionEntityTypeBuilder? HasStorageParameter( [NotNull] this IConventionEntityTypeBuilder entityTypeBuilder, [NotNull] string parameterName, [CanBeNull] object parameterValue, @@ -250,7 +251,7 @@ public static EntityTypeBuilder IsUnlogged( /// /// See: https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-UNLOGGED /// - public static IConventionEntityTypeBuilder IsUnlogged( + public static IConventionEntityTypeBuilder? IsUnlogged( [NotNull] this IConventionEntityTypeBuilder entityTypeBuilder, bool unlogged = true, bool fromDataAnnotation = false) @@ -302,11 +303,18 @@ public static EntityTypeBuilder UseCockroachDbInterleaveInParent( var parentEntity = entityTypeBuilder.Metadata.Model.FindEntityType(parentTableType); if (parentEntity == null) - throw new ArgumentException("Entity not found in model for type: " + parentTableType, nameof(parentTableType)); + { + throw new ArgumentException($"Entity not found in model for type: {parentEntity}", nameof(parentTableType)); + } + + if (StoreObjectIdentifier.Create(parentEntity, StoreObjectType.Table) is not StoreObjectIdentifier tableIdentifier) + { + throw new ArgumentException($"Entity {parentEntity.DisplayName()} is not mapped to a database table"); + } var interleaveInParent = entityTypeBuilder.Metadata.GetCockroachDbInterleaveInParent(); - interleaveInParent.ParentTableSchema = parentEntity.GetSchema(); - interleaveInParent.ParentTableName = parentEntity.GetTableName(); + interleaveInParent.ParentTableSchema = tableIdentifier.Schema; + interleaveInParent.ParentTableName = tableIdentifier.Name; interleaveInParent.InterleavePrefix = interleavePrefix; return entityTypeBuilder; @@ -370,7 +378,7 @@ public static EntityTypeBuilder SetStorageParameter( /// Indicates whether the configuration was specified using a data annotation. /// The same builder instance so that multiple calls can be chained. [Obsolete("Use HasStorageParameter")] - public static IConventionEntityTypeBuilder SetStorageParameter( + public static IConventionEntityTypeBuilder? SetStorageParameter( [NotNull] this IConventionEntityTypeBuilder entityTypeBuilder, [NotNull] string parameterName, [CanBeNull] object parameterValue, diff --git a/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlIndexBuilderExtensions.cs b/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlIndexBuilderExtensions.cs index f846aff405..12b40a5b8e 100644 --- a/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlIndexBuilderExtensions.cs +++ b/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlIndexBuilderExtensions.cs @@ -66,7 +66,7 @@ public static IndexBuilder HasMethod( /// The name of the index. /// Indicates whether the configuration was specified using a data annotation. /// A builder to further configure the index. - public static IConventionIndexBuilder HasMethod( + public static IConventionIndexBuilder? HasMethod( [NotNull] this IConventionIndexBuilder indexBuilder, [CanBeNull] string method, bool fromDataAnnotation = false) @@ -116,7 +116,7 @@ public static bool CanSetMethod( /// A builder to further configure the index. public static IndexBuilder HasOperators( [NotNull] this IndexBuilder indexBuilder, - [CanBeNull] params string[] operators) + [CanBeNull] params string[]? operators) { Check.NotNull(indexBuilder, nameof(indexBuilder)); Check.NullButNotEmpty(operators, nameof(operators)); @@ -137,7 +137,7 @@ public static IndexBuilder HasOperators( /// A builder to further configure the index. public static IndexBuilder HasOperators( [NotNull] this IndexBuilder indexBuilder, - [CanBeNull] params string[] operators) + [CanBeNull] params string[]? operators) => (IndexBuilder)HasOperators((IndexBuilder)indexBuilder, operators); /// @@ -150,9 +150,9 @@ public static IndexBuilder HasOperators( /// The operators to use for each column. /// Indicates whether the configuration was specified using a data annotation. /// A builder to further configure the index. - public static IConventionIndexBuilder HasOperators( + public static IConventionIndexBuilder? HasOperators( [NotNull] this IConventionIndexBuilder indexBuilder, - [CanBeNull] IReadOnlyList operators, + [CanBeNull] IReadOnlyList? operators, bool fromDataAnnotation) { if (indexBuilder.CanSetOperators(operators, fromDataAnnotation)) @@ -177,7 +177,7 @@ public static IConventionIndexBuilder HasOperators( /// true if the index can be configured with the method. public static bool CanSetOperators( [NotNull] this IConventionIndexBuilder indexBuilder, - [CanBeNull] IReadOnlyList operators, + [CanBeNull] IReadOnlyList? operators, bool fromDataAnnotation) { Check.NotNull(indexBuilder, nameof(indexBuilder)); @@ -250,7 +250,7 @@ public static IndexBuilder IsTsVectorExpressionIndex( /// The same builder instance if the configuration was applied, /// null otherwise. /// - public static IConventionIndexBuilder IsTsVectorExpressionIndex( + public static IConventionIndexBuilder? IsTsVectorExpressionIndex( [NotNull] this IConventionIndexBuilder indexBuilder, [CanBeNull] string config) { @@ -306,7 +306,7 @@ public static bool CanSetIsTsVectorExpressionIndex( /// A builder to further configure the index. public static IndexBuilder UseCollation( [NotNull] this IndexBuilder indexBuilder, - [CanBeNull] params string[] values) + [CanBeNull] params string[]? values) { Check.NotNull(indexBuilder, nameof(indexBuilder)); Check.NullButNotEmpty(values, nameof(values)); @@ -327,7 +327,7 @@ public static IndexBuilder UseCollation( /// A builder to further configure the index. public static IndexBuilder UseCollation( [NotNull] this IndexBuilder indexBuilder, - [CanBeNull] params string[] values) + [CanBeNull] params string[]? values) => (IndexBuilder)UseCollation((IndexBuilder)indexBuilder, values); /// @@ -340,9 +340,9 @@ public static IndexBuilder UseCollation( /// The sort options to use for each column. /// Indicates whether the configuration was specified using a data annotation. /// A builder to further configure the index. - public static IConventionIndexBuilder UseCollation( + public static IConventionIndexBuilder? UseCollation( [NotNull] this IConventionIndexBuilder indexBuilder, - [CanBeNull] IReadOnlyList values, + [CanBeNull] IReadOnlyList? values, bool fromDataAnnotation) { if (indexBuilder.CanSetCollation(values, fromDataAnnotation)) @@ -367,7 +367,7 @@ public static IConventionIndexBuilder UseCollation( /// A builder to further configure the index. public static bool CanSetCollation( [NotNull] this IConventionIndexBuilder indexBuilder, - [CanBeNull] IReadOnlyList values, + [CanBeNull] IReadOnlyList? values, bool fromDataAnnotation) { Check.NotNull(indexBuilder, nameof(indexBuilder)); @@ -390,7 +390,7 @@ public static bool CanSetCollation( /// A builder to further configure the index. public static IndexBuilder HasSortOrder( [NotNull] this IndexBuilder indexBuilder, - [CanBeNull] params SortOrder[] values) + [CanBeNull] params SortOrder[]? values) { Check.NotNull(indexBuilder, nameof(indexBuilder)); Check.NullButNotEmpty(values, nameof(values)); @@ -412,7 +412,7 @@ public static IndexBuilder HasSortOrder( /// A builder to further configure the index. public static IndexBuilder HasSortOrder( [NotNull] this IndexBuilder indexBuilder, - [CanBeNull] params SortOrder[] values) + [CanBeNull] params SortOrder[]? values) => (IndexBuilder)HasSortOrder((IndexBuilder)indexBuilder, values); /// @@ -425,9 +425,9 @@ public static IndexBuilder HasSortOrder( /// Indicates whether the configuration was specified using a data annotation. /// The sort order to use for each column. /// A builder to further configure the index. - public static IConventionIndexBuilder HasSortOrder( + public static IConventionIndexBuilder? HasSortOrder( [NotNull] this IConventionIndexBuilder indexBuilder, - [CanBeNull] IReadOnlyList values, + [CanBeNull] IReadOnlyList? values, bool fromDataAnnotation) { if (indexBuilder.CanSetSortOrder(values, fromDataAnnotation)) @@ -456,7 +456,7 @@ public static IConventionIndexBuilder HasSortOrder( /// A builder to further configure the index. public static bool CanSetSortOrder( [NotNull] this IConventionIndexBuilder indexBuilder, - [CanBeNull] IReadOnlyList values, + [CanBeNull] IReadOnlyList? values, bool fromDataAnnotation) { Check.NotNull(indexBuilder, nameof(indexBuilder)); @@ -479,7 +479,7 @@ public static bool CanSetSortOrder( /// A builder to further configure the index. public static IndexBuilder HasNullSortOrder( [NotNull] this IndexBuilder indexBuilder, - [CanBeNull] params NullSortOrder[] values) + [CanBeNull] params NullSortOrder[]? values) { Check.NotNull(indexBuilder, nameof(indexBuilder)); Check.NullButNotEmpty(values, nameof(values)); @@ -503,7 +503,7 @@ public static IndexBuilder HasNullSortOrder( /// A builder to further configure the index. public static IndexBuilder HasNullSortOrder( [NotNull] this IndexBuilder indexBuilder, - [CanBeNull] params NullSortOrder[] values) + [CanBeNull] params NullSortOrder[]? values) => (IndexBuilder)HasNullSortOrder((IndexBuilder)indexBuilder, values); /// @@ -516,9 +516,9 @@ public static IndexBuilder HasNullSortOrder( /// The sort order to use for each column. /// Indicates whether the configuration was specified using a data annotation. /// A builder to further configure the index. - public static IConventionIndexBuilder HasNullSortOrder( + public static IConventionIndexBuilder? HasNullSortOrder( [NotNull] this IConventionIndexBuilder indexBuilder, - [CanBeNull] IReadOnlyList values, + [CanBeNull] IReadOnlyList? values, bool fromDataAnnotation) { if (indexBuilder.CanSetNullSortOrder(values, fromDataAnnotation)) @@ -546,7 +546,7 @@ public static IConventionIndexBuilder HasNullSortOrder( /// A builder to further configure the index. public static bool CanSetNullSortOrder( [NotNull] this IConventionIndexBuilder indexBuilder, - [CanBeNull] IReadOnlyList values, + [CanBeNull] IReadOnlyList? values, bool fromDataAnnotation) { Check.NotNull(indexBuilder, nameof(indexBuilder)); @@ -644,7 +644,7 @@ public static IndexBuilder IncludeProperties( /// An array of property names to be used in INCLUDE clause. /// Indicates whether the configuration was specified using a data annotation. /// A builder to further configure the index. - public static IConventionIndexBuilder IncludeProperties( + public static IConventionIndexBuilder? IncludeProperties( [NotNull] this IConventionIndexBuilder indexBuilder, [NotNull] IReadOnlyList propertyNames, bool fromDataAnnotation = false) @@ -668,7 +668,7 @@ public static IConventionIndexBuilder IncludeProperties( /// true if the given include properties can be set. public static bool CanSetIncludeProperties( [NotNull] this IConventionIndexBuilder indexBuilder, - [CanBeNull] IReadOnlyList propertyNames, + [CanBeNull] IReadOnlyList? propertyNames, bool fromDataAnnotation = false) { Check.NotNull(indexBuilder, nameof(indexBuilder)); @@ -726,7 +726,7 @@ public static IndexBuilder IsCreatedConcurrently([NotNull] thi /// A value indicating whether the index is created with the "concurrently" option. /// Indicates whether the configuration was specified using a data annotation. /// A builder to further configure the index. - public static IConventionIndexBuilder IsCreatedConcurrently( + public static IConventionIndexBuilder? IsCreatedConcurrently( [NotNull] this IConventionIndexBuilder indexBuilder, bool? createdConcurrently, bool fromDataAnnotation = false) @@ -806,7 +806,7 @@ public static IndexBuilder HasCollation( /// Indicates whether the configuration was specified using a data annotation. /// A builder to further configure the index. [Obsolete("Use UseCollation")] - public static IConventionIndexBuilder HasCollation( + public static IConventionIndexBuilder? HasCollation( [NotNull] this IConventionIndexBuilder indexBuilder, [CanBeNull] IReadOnlyList values, bool fromDataAnnotation) diff --git a/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlModelBuilderExtensions.cs b/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlModelBuilderExtensions.cs index 8b03eb65bc..67740365dd 100644 --- a/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlModelBuilderExtensions.cs +++ b/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlModelBuilderExtensions.cs @@ -31,8 +31,8 @@ public static class NpgsqlModelBuilderExtensions /// The same builder instance so that multiple calls can be chained. public static ModelBuilder UseHiLo( [NotNull] this ModelBuilder modelBuilder, - [CanBeNull] string name = null, - [CanBeNull] string schema = null) + [CanBeNull] string? name = null, + [CanBeNull] string? schema = null) { Check.NotNull(modelBuilder, nameof(modelBuilder)); Check.NullButNotEmpty(name, nameof(name)); @@ -63,10 +63,10 @@ public static ModelBuilder UseHiLo( /// The schema of the sequence. /// Indicates whether the configuration was specified using a data annotation. /// A builder to further configure the sequence. - public static IConventionSequenceBuilder HasHiLoSequence( + public static IConventionSequenceBuilder? HasHiLoSequence( [NotNull] this IConventionModelBuilder modelBuilder, - [CanBeNull] string name, - [CanBeNull] string schema, + [CanBeNull] string? name, + [CanBeNull] string? schema, bool fromDataAnnotation = false) { if (!modelBuilder.CanSetHiLoSequence(name, schema)) @@ -90,8 +90,8 @@ public static IConventionSequenceBuilder HasHiLoSequence( /// true if the given name and schema can be set for the hi-lo sequence. public static bool CanSetHiLoSequence( [NotNull] this IConventionModelBuilder modelBuilder, - [CanBeNull] string name, - [CanBeNull] string schema, + [CanBeNull] string? name, + [CanBeNull] string? schema, bool fromDataAnnotation = false) { Check.NotNull(modelBuilder, nameof(modelBuilder)); @@ -213,7 +213,7 @@ public static ModelBuilder UseIdentityColumns( /// /// The same builder instance if the configuration was applied, null otherwise. /// - public static IConventionModelBuilder HasValueGenerationStrategy( + public static IConventionModelBuilder? HasValueGenerationStrategy( [NotNull] this IConventionModelBuilder modelBuilder, NpgsqlValueGenerationStrategy? valueGenerationStrategy, bool fromDataAnnotation = false) @@ -272,9 +272,9 @@ public static bool CanSetValueGenerationStrategy( [NotNull] public static ModelBuilder HasPostgresExtension( [NotNull] this ModelBuilder modelBuilder, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, - [CanBeNull] string version = null) + [CanBeNull] string? version = null) { Check.NotNull(modelBuilder, nameof(modelBuilder)); Check.NullButNotEmpty(schema, nameof(schema)); @@ -324,7 +324,7 @@ public static ModelBuilder HasPostgresExtension( [NotNull] public static ModelBuilder HasPostgresEnum( [NotNull] this ModelBuilder modelBuilder, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, [NotNull] string[] labels) { @@ -376,9 +376,9 @@ public static ModelBuilder HasPostgresEnum( [NotNull] public static ModelBuilder HasPostgresEnum( [NotNull] this ModelBuilder modelBuilder, - [CanBeNull] string schema = null, - [CanBeNull] string name = null, - [CanBeNull] INpgsqlNameTranslator nameTranslator = null) + [CanBeNull] string? schema = null, + [CanBeNull] string? name = null, + [CanBeNull] INpgsqlNameTranslator? nameTranslator = null) where TEnum : struct, Enum { if (nameTranslator == null) @@ -432,13 +432,13 @@ public static ModelBuilder UseDatabaseTemplate( [NotNull] public static ModelBuilder HasPostgresRange( [NotNull] this ModelBuilder modelBuilder, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, [NotNull] string subtype, - [CanBeNull] string canonicalFunction = null, - [CanBeNull] string subtypeOpClass = null, - [CanBeNull] string collation = null, - [CanBeNull] string subtypeDiff = null) + [CanBeNull] string? canonicalFunction = null, + [CanBeNull] string? subtypeOpClass = null, + [CanBeNull] string? collation = null, + [CanBeNull] string? subtypeDiff = null) { Check.NotNull(modelBuilder, nameof(modelBuilder)); Check.NotEmpty(name, nameof(name)); @@ -512,7 +512,7 @@ public static ModelBuilder HasCollation( [NotNull] this ModelBuilder modelBuilder, [NotNull] string name, [NotNull] string locale, - [CanBeNull] string provider = null, + [CanBeNull] string? provider = null, bool? deterministic = null) => modelBuilder.HasCollation(schema: null, name, locale, provider: provider, deterministic: deterministic); @@ -537,10 +537,10 @@ public static ModelBuilder HasCollation( [NotNull] public static ModelBuilder HasCollation( [NotNull] this ModelBuilder modelBuilder, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, [NotNull] string locale, - [CanBeNull] string provider = null, + [CanBeNull] string? provider = null, bool? deterministic = null) { Check.NotNull(modelBuilder, nameof(modelBuilder)); @@ -579,11 +579,11 @@ public static ModelBuilder HasCollation( [NotNull] public static ModelBuilder HasCollation( [NotNull] this ModelBuilder modelBuilder, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, [NotNull] string lcCollate, [NotNull] string lcCtype, - [CanBeNull] string provider = null, + [CanBeNull] string? provider = null, bool? deterministic = null) { Check.NotNull(modelBuilder, nameof(modelBuilder)); @@ -623,7 +623,7 @@ public static ModelBuilder HasCollation( /// The model builder. /// The collation. /// A builder to further configure the property. - public static ModelBuilder UseDefaultColumnCollation([NotNull] this ModelBuilder modelBuilder, [CanBeNull] string collation) + public static ModelBuilder UseDefaultColumnCollation([NotNull] this ModelBuilder modelBuilder, [CanBeNull] string? collation) { Check.NotNull(modelBuilder, nameof(modelBuilder)); Check.NullButNotEmpty(collation, nameof(collation)); @@ -652,9 +652,9 @@ public static ModelBuilder UseDefaultColumnCollation([NotNull] this ModelBuilder /// The collation. /// Indicates whether the configuration was specified using a data annotation. /// A builder to further configure the property. - public static IConventionModelBuilder UseDefaultColumnCollation( + public static IConventionModelBuilder? UseDefaultColumnCollation( [NotNull] this IConventionModelBuilder modelBuilder, - [CanBeNull] string collation, + [CanBeNull] string? collation, bool fromDataAnnotation = false) { if (modelBuilder.CanSetDefaultColumnCollation(collation, fromDataAnnotation)) @@ -675,7 +675,7 @@ public static IConventionModelBuilder UseDefaultColumnCollation( /// true if the given value can be set as the collation. public static bool CanSetDefaultColumnCollation( [NotNull] this IConventionModelBuilder modelBuilder, - [CanBeNull] string collation, + [CanBeNull] string? collation, bool fromDataAnnotation = false) { Check.NotNull(modelBuilder, nameof(modelBuilder)); diff --git a/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlPropertyBuilderExtensions.cs b/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlPropertyBuilderExtensions.cs index cf8c3cacc9..213e56222a 100644 --- a/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlPropertyBuilderExtensions.cs +++ b/src/EFCore.PG/Extensions/BuilderExtensions/NpgsqlPropertyBuilderExtensions.cs @@ -32,8 +32,8 @@ public static class NpgsqlPropertyBuilderExtensions /// The same builder instance so that multiple calls can be chained. public static PropertyBuilder UseHiLo( [NotNull] this PropertyBuilder propertyBuilder, - [CanBeNull] string name = null, - [CanBeNull] string schema = null) + [CanBeNull] string? name = null, + [CanBeNull] string? schema = null) { Check.NotNull(propertyBuilder, nameof(propertyBuilder)); Check.NullButNotEmpty(name, nameof(name)); @@ -68,8 +68,8 @@ public static PropertyBuilder UseHiLo( /// The same builder instance so that multiple calls can be chained. public static PropertyBuilder UseHiLo( [NotNull] this PropertyBuilder propertyBuilder, - [CanBeNull] string name = null, - [CanBeNull] string schema = null) + [CanBeNull] string? name = null, + [CanBeNull] string? schema = null) => (PropertyBuilder)UseHiLo((PropertyBuilder)propertyBuilder, name, schema); /// @@ -81,10 +81,10 @@ public static PropertyBuilder UseHiLo( /// The schema of the sequence. /// Indicates whether the configuration was specified using a data annotation. /// A builder to further configure the sequence. - public static IConventionSequenceBuilder HasHiLoSequence( + public static IConventionSequenceBuilder? HasHiLoSequence( [NotNull] this IConventionPropertyBuilder propertyBuilder, - [CanBeNull] string name, - [CanBeNull] string schema, + [CanBeNull] string? name, + [CanBeNull] string? schema, bool fromDataAnnotation = false) { if (!propertyBuilder.CanSetHiLoSequence(name, schema)) @@ -110,8 +110,8 @@ public static IConventionSequenceBuilder HasHiLoSequence( /// true if the given name and schema can be set for the hi-lo sequence. public static bool CanSetHiLoSequence( [NotNull] this IConventionPropertyBuilder propertyBuilder, - [CanBeNull] string name, - [CanBeNull] string schema, + [CanBeNull] string? name, + [CanBeNull] string? schema, bool fromDataAnnotation = false) { Check.NotNull(propertyBuilder, nameof(propertyBuilder)); @@ -303,7 +303,7 @@ public static PropertyBuilder UseIdentityColumn( /// /// The same builder instance if the configuration was applied, null otherwise. /// - public static IConventionPropertyBuilder HasValueGenerationStrategy( + public static IConventionPropertyBuilder? HasValueGenerationStrategy( [NotNull] this IConventionPropertyBuilder propertyBuilder, NpgsqlValueGenerationStrategy? valueGenerationStrategy, bool fromDataAnnotation = false) @@ -461,7 +461,7 @@ public static PropertyBuilder HasIdentityOptions( /// The minimum value is 1 (only one value can be generated at a time, i.e., no cache), and this is also the default. /// /// The same builder instance so that multiple calls can be chained. - public static IConventionPropertyBuilder HasIdentityOptions( + public static IConventionPropertyBuilder? HasIdentityOptions( [NotNull] this IConventionPropertyBuilder propertyBuilder, long? startValue = null, long? incrementBy = null, @@ -632,8 +632,7 @@ public static PropertyBuilder IsGeneratedTsVectorColumn( /// The builder for the property being configured. /// /// - /// The text search configuration for this generated tsvector property, or null if this is not a - /// generated tsvector property. + /// The text search configuration for this generated tsvector property. /// /// /// See https://www.postgresql.org/docs/current/textsearch-controls.html for more information. @@ -645,10 +644,10 @@ public static PropertyBuilder IsGeneratedTsVectorColumn( /// The same builder instance if the configuration was applied, /// null otherwise. /// - public static IConventionPropertyBuilder IsGeneratedTsVectorColumn( + public static IConventionPropertyBuilder? IsGeneratedTsVectorColumn( [NotNull] this IConventionPropertyBuilder propertyBuilder, - [CanBeNull] string config, - [CanBeNull] IReadOnlyList includedPropertyNames, + [NotNull] string config, + [NotNull] IReadOnlyList includedPropertyNames, bool fromDataAnnotation = false) { Check.NotNull(propertyBuilder, nameof(propertyBuilder)); @@ -683,8 +682,8 @@ public static IConventionPropertyBuilder IsGeneratedTsVectorColumn( /// true if the property can be configured as a full-text search tsvector column. public static bool CanSetIsGeneratedTsVectorColumn( [NotNull] this IConventionPropertyBuilder propertyBuilder, - [CanBeNull] string config, - [CanBeNull] IReadOnlyList includedPropertyNames, + [CanBeNull] string? config, + [CanBeNull] IReadOnlyList? includedPropertyNames, bool fromDataAnnotation = false) { Check.NotNull(propertyBuilder, nameof(propertyBuilder)); diff --git a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlDbFunctionsExtensions.cs b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlDbFunctionsExtensions.cs index 6647550cc9..c5d3089b1a 100644 --- a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlDbFunctionsExtensions.cs +++ b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlDbFunctionsExtensions.cs @@ -19,9 +19,9 @@ public static class NpgsqlDbFunctionsExtensions /// The pattern which may involve wildcards %,_,[,],^. /// if there is a match. public static bool ILike( - [CanBeNull] this DbFunctions _, - [CanBeNull] string matchExpression, - [CanBeNull] string pattern) + [NotNull] this DbFunctions _, + [NotNull] string matchExpression, + [NotNull] string pattern) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ILike))); // ReSharper disable once InconsistentNaming @@ -37,10 +37,10 @@ public static bool ILike( /// /// if there is a match. public static bool ILike( - [CanBeNull] this DbFunctions _, - [CanBeNull] string matchExpression, - [CanBeNull] string pattern, - [CanBeNull] string escapeCharacter) + [NotNull] this DbFunctions _, + [NotNull] string matchExpression, + [NotNull] string pattern, + [NotNull] string escapeCharacter) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ILike))); /// @@ -49,7 +49,7 @@ public static bool ILike( /// The instance. /// The string that is to be reversed. /// The reversed string. - public static string Reverse([CanBeNull] this DbFunctions _, [CanBeNull] string value) + public static string Reverse([NotNull] this DbFunctions _, [NotNull] string value) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Reverse))); } } diff --git a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlFullTextSearchDbFunctionsExtensions.cs b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlFullTextSearchDbFunctionsExtensions.cs index 57ccd2d730..fcca6de540 100644 --- a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlFullTextSearchDbFunctionsExtensions.cs +++ b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlFullTextSearchDbFunctionsExtensions.cs @@ -15,7 +15,7 @@ public static class NpgsqlFullTextSearchDbFunctionsExtensions /// /// https://www.postgresql.org/docs/current/static/functions-textsearch.html /// - public static NpgsqlTsVector ArrayToTsVector([CanBeNull] this DbFunctions _, [NotNull] string[] lexemes) + public static NpgsqlTsVector ArrayToTsVector([NotNull] this DbFunctions _, [NotNull] string[] lexemes) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ArrayToTsVector))); /// @@ -24,7 +24,7 @@ public static NpgsqlTsVector ArrayToTsVector([CanBeNull] this DbFunctions _, [No /// /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-DOCUMENTS /// - public static NpgsqlTsVector ToTsVector([CanBeNull] this DbFunctions _, [NotNull] string document) + public static NpgsqlTsVector ToTsVector([NotNull] this DbFunctions _, [NotNull] string document) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ToTsVector))); /// @@ -35,7 +35,7 @@ public static NpgsqlTsVector ToTsVector([CanBeNull] this DbFunctions _, [NotNull /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-DOCUMENTS /// public static NpgsqlTsVector ToTsVector( - [CanBeNull] this DbFunctions _, + [NotNull] this DbFunctions _, [NotNull] string config, [NotNull] string document) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ToTsVector))); @@ -46,7 +46,7 @@ public static NpgsqlTsVector ToTsVector( /// /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// - public static NpgsqlTsQuery PlainToTsQuery([CanBeNull] this DbFunctions _, [NotNull] string query) + public static NpgsqlTsQuery PlainToTsQuery([NotNull] this DbFunctions _, [NotNull] string query) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(PlainToTsQuery))); /// @@ -57,7 +57,7 @@ public static NpgsqlTsQuery PlainToTsQuery([CanBeNull] this DbFunctions _, [NotN /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// public static NpgsqlTsQuery PlainToTsQuery( - [CanBeNull] this DbFunctions _, + [NotNull] this DbFunctions _, [NotNull] string config, [NotNull] string query) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(PlainToTsQuery))); @@ -68,7 +68,7 @@ public static NpgsqlTsQuery PlainToTsQuery( /// /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// - public static NpgsqlTsQuery PhraseToTsQuery([CanBeNull] this DbFunctions _, [NotNull] string query) + public static NpgsqlTsQuery PhraseToTsQuery([NotNull] this DbFunctions _, [NotNull] string query) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(PhraseToTsQuery))); /// @@ -79,7 +79,7 @@ public static NpgsqlTsQuery PhraseToTsQuery([CanBeNull] this DbFunctions _, [Not /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// public static NpgsqlTsQuery PhraseToTsQuery( - [CanBeNull] this DbFunctions _, + [NotNull] this DbFunctions _, [NotNull] string config, [NotNull] string query) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(PhraseToTsQuery))); @@ -92,7 +92,7 @@ public static NpgsqlTsQuery PhraseToTsQuery( /// /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// - public static NpgsqlTsQuery ToTsQuery([CanBeNull] this DbFunctions _, [NotNull] string query) + public static NpgsqlTsQuery ToTsQuery([NotNull] this DbFunctions _, [NotNull] string query) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ToTsQuery))); /// @@ -105,7 +105,7 @@ public static NpgsqlTsQuery ToTsQuery([CanBeNull] this DbFunctions _, [NotNull] /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// public static NpgsqlTsQuery ToTsQuery( - [CanBeNull] this DbFunctions _, + [NotNull] this DbFunctions _, [NotNull] string config, [NotNull] string query) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ToTsQuery))); @@ -116,7 +116,7 @@ public static NpgsqlTsQuery ToTsQuery( /// /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// - public static NpgsqlTsQuery WebSearchToTsQuery([CanBeNull] this DbFunctions _, [NotNull] string query) + public static NpgsqlTsQuery WebSearchToTsQuery([NotNull] this DbFunctions _, [NotNull] string query) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(WebSearchToTsQuery))); /// @@ -127,7 +127,7 @@ public static NpgsqlTsQuery WebSearchToTsQuery([CanBeNull] this DbFunctions _, [ /// http://www.postgresql.org/docs/current/static/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES /// public static NpgsqlTsQuery WebSearchToTsQuery( - [CanBeNull] this DbFunctions _, + [NotNull] this DbFunctions _, [NotNull] string config, [NotNull] string query) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(WebSearchToTsQuery))); @@ -140,11 +140,11 @@ public static NpgsqlTsQuery WebSearchToTsQuery( /// The text to remove the diacritics. /// /// The method call is translated to unaccent(regdictionary, text). - /// + /// /// See https://www.postgresql.org/docs/current/unaccent.html. /// /// A string without diacritics. - public static string Unaccent([CanBeNull] this DbFunctions _, [NotNull] string regDictionary, [CanBeNull] string text) + public static string Unaccent([NotNull] this DbFunctions _, [NotNull] string regDictionary, [NotNull] string text) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Unaccent))); /// @@ -158,7 +158,7 @@ public static string Unaccent([CanBeNull] this DbFunctions _, [NotNull] string r /// See https://www.postgresql.org/docs/current/unaccent.html. /// /// A string without diacritics. - public static string Unaccent([CanBeNull] this DbFunctions _, [CanBeNull] string text) + public static string Unaccent([NotNull] this DbFunctions _, [NotNull] string text) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Unaccent))); } } diff --git a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlFuzzyStringMatchDbFunctionsExtensions.cs b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlFuzzyStringMatchDbFunctionsExtensions.cs index 42c1a53d37..68bbb6532c 100644 --- a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlFuzzyStringMatchDbFunctionsExtensions.cs +++ b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlFuzzyStringMatchDbFunctionsExtensions.cs @@ -14,7 +14,7 @@ public static class NpgsqlFuzzyStringMatchDbFunctionsExtensions /// /// See https://www.postgresql.org/docs/current/fuzzystrmatch.html. /// - public static string FuzzyStringMatchSoundex([CanBeNull] this DbFunctions _, [NotNull] string text) + public static string FuzzyStringMatchSoundex([NotNull] this DbFunctions _, [NotNull] string text) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(FuzzyStringMatchSoundex))); /// @@ -28,7 +28,7 @@ public static string FuzzyStringMatchSoundex([CanBeNull] this DbFunctions _, [No /// /// See https://www.postgresql.org/docs/current/fuzzystrmatch.html. /// - public static int FuzzyStringMatchDifference([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static int FuzzyStringMatchDifference([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(FuzzyStringMatchDifference))); /// @@ -39,7 +39,7 @@ public static int FuzzyStringMatchDifference([CanBeNull] this DbFunctions _, [No /// /// See https://www.postgresql.org/docs/current/fuzzystrmatch.html. /// - public static int FuzzyStringMatchLevenshtein([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static int FuzzyStringMatchLevenshtein([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(FuzzyStringMatchLevenshtein))); /// @@ -50,7 +50,7 @@ public static int FuzzyStringMatchLevenshtein([CanBeNull] this DbFunctions _, [N /// /// See https://www.postgresql.org/docs/current/fuzzystrmatch.html. /// - public static int FuzzyStringMatchLevenshtein([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target, int insertionCost, int deletionCost, int substitutionCost) + public static int FuzzyStringMatchLevenshtein([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target, int insertionCost, int deletionCost, int substitutionCost) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(FuzzyStringMatchLevenshtein))); /// @@ -63,7 +63,7 @@ public static int FuzzyStringMatchLevenshtein([CanBeNull] this DbFunctions _, [N /// /// See https://www.postgresql.org/docs/current/fuzzystrmatch.html. /// - public static int FuzzyStringMatchLevenshteinLessEqual([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target, int maximumDistance) + public static int FuzzyStringMatchLevenshteinLessEqual([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target, int maximumDistance) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(FuzzyStringMatchLevenshteinLessEqual))); /// @@ -76,7 +76,7 @@ public static int FuzzyStringMatchLevenshteinLessEqual([CanBeNull] this DbFuncti /// /// See https://www.postgresql.org/docs/current/fuzzystrmatch.html. /// - public static int FuzzyStringMatchLevenshteinLessEqual([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target, int insertionCost, int deletionCost, int substitutionCost, int maximumDistance) + public static int FuzzyStringMatchLevenshteinLessEqual([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target, int insertionCost, int deletionCost, int substitutionCost, int maximumDistance) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(FuzzyStringMatchLevenshteinLessEqual))); /// @@ -87,7 +87,7 @@ public static int FuzzyStringMatchLevenshteinLessEqual([CanBeNull] this DbFuncti /// /// See https://www.postgresql.org/docs/current/fuzzystrmatch.html. /// - public static string FuzzyStringMatchMetaphone([CanBeNull] this DbFunctions _, [NotNull] string text, int maximumOutputLength) + public static string FuzzyStringMatchMetaphone([NotNull] this DbFunctions _, [NotNull] string text, int maximumOutputLength) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(FuzzyStringMatchMetaphone))); /// @@ -98,7 +98,7 @@ public static string FuzzyStringMatchMetaphone([CanBeNull] this DbFunctions _, [ /// /// See https://www.postgresql.org/docs/current/fuzzystrmatch.html. /// - public static string FuzzyStringMatchDoubleMetaphone([CanBeNull] this DbFunctions _, [NotNull] string text) + public static string FuzzyStringMatchDoubleMetaphone([NotNull] this DbFunctions _, [NotNull] string text) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(FuzzyStringMatchDoubleMetaphone))); /// @@ -109,7 +109,7 @@ public static string FuzzyStringMatchDoubleMetaphone([CanBeNull] this DbFunction /// /// See https://www.postgresql.org/docs/current/fuzzystrmatch.html. /// - public static string FuzzyStringMatchDoubleMetaphoneAlt([CanBeNull] this DbFunctions _, [NotNull] string text) + public static string FuzzyStringMatchDoubleMetaphoneAlt([NotNull] this DbFunctions _, [NotNull] string text) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(FuzzyStringMatchDoubleMetaphoneAlt))); } } diff --git a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlJsonDbFunctionsExtensions.cs b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlJsonDbFunctionsExtensions.cs index 979368af33..39286f6360 100644 --- a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlJsonDbFunctionsExtensions.cs +++ b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlJsonDbFunctionsExtensions.cs @@ -31,7 +31,7 @@ public static class NpgsqlJsonDbFunctionsExtensions /// See https://www.postgresql.org/docs/current/functions-json.html. /// public static bool JsonContains( - [CanBeNull] this DbFunctions _, [NotNull] object json, [NotNull] object contained) + [NotNull] this DbFunctions _, [NotNull] object json, [NotNull] object contained) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(JsonContains))); /// @@ -50,7 +50,7 @@ public static bool JsonContains( /// See https://www.postgresql.org/docs/current/functions-json.html. /// public static bool JsonContained( - [CanBeNull] this DbFunctions _, [NotNull] object contained, [NotNull] object json) + [NotNull] this DbFunctions _, [NotNull] object contained, [NotNull] object json) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(JsonContained))); /// @@ -66,7 +66,7 @@ public static bool JsonContained( /// /// See https://www.postgresql.org/docs/current/functions-json.html. /// - public static bool JsonExists([CanBeNull] this DbFunctions _, [NotNull] object json, [NotNull] string key) + public static bool JsonExists([NotNull] this DbFunctions _, [NotNull] object json, [NotNull] string key) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(JsonExists))); /// @@ -83,7 +83,7 @@ public static bool JsonExists([CanBeNull] this DbFunctions _, [NotNull] object j /// See https://www.postgresql.org/docs/current/functions-json.html. /// public static bool JsonExistAny( - [CanBeNull] this DbFunctions _, [NotNull] object json, [NotNull] params string[] keys) + [NotNull] this DbFunctions _, [NotNull] object json, [NotNull] params string[] keys) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(JsonExistAny))); /// @@ -100,7 +100,7 @@ public static bool JsonExistAny( /// See https://www.postgresql.org/docs/current/functions-json.html. /// public static bool JsonExistAll( - [CanBeNull] this DbFunctions _, [NotNull] object json, [NotNull] params string[] keys) + [NotNull] this DbFunctions _, [NotNull] object json, [NotNull] params string[] keys) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(JsonExistAll))); /// @@ -114,7 +114,7 @@ public static bool JsonExistAll( /// /// See https://www.postgresql.org/docs/current/functions-json.html. /// - public static string JsonTypeof([CanBeNull] this DbFunctions _, [NotNull] object json) + public static string JsonTypeof([NotNull] this DbFunctions _, [NotNull] object json) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(JsonTypeof))); } } diff --git a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlNetworkDbFunctionsExtensions.cs b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlNetworkDbFunctionsExtensions.cs index 72188cd684..852c1179ec 100644 --- a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlNetworkDbFunctionsExtensions.cs +++ b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlNetworkDbFunctionsExtensions.cs @@ -29,7 +29,7 @@ public static class NpgsqlNetworkDbFunctionsExtensions /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static bool LessThan([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + public static bool LessThan([NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(LessThan))); /// @@ -44,7 +44,7 @@ public static bool LessThan([CanBeNull] this DbFunctions _, [NotNull] IPAddress /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static bool LessThan([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + public static bool LessThan([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(LessThan))); /// @@ -60,7 +60,7 @@ public static bool LessThan([CanBeNull] this DbFunctions _, (IPAddress Address, /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool LessThan( - [CanBeNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) + [NotNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(LessThan))); /// @@ -76,7 +76,7 @@ public static bool LessThan( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool LessThanOrEqual( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(LessThanOrEqual))); /// @@ -92,7 +92,7 @@ public static bool LessThanOrEqual( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool LessThanOrEqual( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(LessThanOrEqual))); /// @@ -108,7 +108,7 @@ public static bool LessThanOrEqual( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool LessThanOrEqual( - [CanBeNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) + [NotNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(LessThanOrEqual))); /// @@ -124,7 +124,7 @@ public static bool LessThanOrEqual( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool GreaterThanOrEqual( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(GreaterThanOrEqual))); /// @@ -140,7 +140,7 @@ public static bool GreaterThanOrEqual( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool GreaterThanOrEqual( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(GreaterThanOrEqual))); /// @@ -156,7 +156,7 @@ public static bool GreaterThanOrEqual( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool GreaterThanOrEqual( - [CanBeNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) + [NotNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(GreaterThanOrEqual))); /// @@ -172,7 +172,7 @@ public static bool GreaterThanOrEqual( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool GreaterThan( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(GreaterThan))); /// @@ -187,7 +187,7 @@ public static bool GreaterThan( /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static bool GreaterThan([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + public static bool GreaterThan([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(GreaterThan))); /// @@ -203,7 +203,7 @@ public static bool GreaterThan([CanBeNull] this DbFunctions _, (IPAddress Addres /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool GreaterThan( - [CanBeNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) + [NotNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(GreaterThan))); #endregion @@ -223,7 +223,7 @@ public static bool GreaterThan( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainedBy( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainedBy))); /// @@ -239,7 +239,7 @@ public static bool ContainedBy( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainedBy( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainedBy))); /// @@ -255,7 +255,7 @@ public static bool ContainedBy( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainedBy( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainedBy))); /// @@ -271,7 +271,7 @@ public static bool ContainedBy( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainedByOrEqual( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainedByOrEqual))); /// @@ -287,7 +287,7 @@ public static bool ContainedByOrEqual( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainedByOrEqual( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainedByOrEqual))); /// @@ -302,7 +302,7 @@ public static bool ContainedByOrEqual( /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static bool ContainedByOrEqual([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + public static bool ContainedByOrEqual([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainedByOrEqual))); /// @@ -317,7 +317,7 @@ public static bool ContainedByOrEqual([CanBeNull] this DbFunctions _, (IPAddress /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static bool Contains([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + public static bool Contains([NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Contains))); /// @@ -333,7 +333,7 @@ public static bool Contains([CanBeNull] this DbFunctions _, [NotNull] IPAddress /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool Contains( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Contains))); /// @@ -349,7 +349,7 @@ public static bool Contains( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool Contains( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Contains))); /// @@ -365,7 +365,7 @@ public static bool Contains( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainsOrEqual( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainsOrEqual))); /// @@ -381,7 +381,7 @@ public static bool ContainsOrEqual( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainsOrEqual( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainsOrEqual))); /// @@ -397,7 +397,7 @@ public static bool ContainsOrEqual( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainsOrEqual( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainsOrEqual))); /// @@ -413,7 +413,7 @@ public static bool ContainsOrEqual( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainsOrContainedBy( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainsOrContainedBy))); /// @@ -429,7 +429,7 @@ public static bool ContainsOrContainedBy( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainsOrContainedBy( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainsOrContainedBy))); /// @@ -445,7 +445,7 @@ public static bool ContainsOrContainedBy( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainsOrContainedBy( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainsOrContainedBy))); /// @@ -461,7 +461,7 @@ public static bool ContainsOrContainedBy( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool ContainsOrContainedBy( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(ContainsOrContainedBy))); #endregion @@ -479,7 +479,7 @@ public static bool ContainsOrContainedBy( /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static IPAddress BitwiseNot([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet) + public static IPAddress BitwiseNot([NotNull] this DbFunctions _, [NotNull] IPAddress inet) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(BitwiseNot))); /// @@ -494,7 +494,7 @@ public static IPAddress BitwiseNot([CanBeNull] this DbFunctions _, [NotNull] IPA /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static (IPAddress Address, int Subnet) BitwiseNot( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(BitwiseNot))); /// @@ -508,7 +508,7 @@ public static (IPAddress Address, int Subnet) BitwiseNot( /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static PhysicalAddress BitwiseNot([CanBeNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr) + public static PhysicalAddress BitwiseNot([NotNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(BitwiseNot))); /// @@ -524,7 +524,7 @@ public static PhysicalAddress BitwiseNot([CanBeNull] this DbFunctions _, [NotNul /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static IPAddress BitwiseAnd( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(BitwiseAnd))); /// @@ -540,7 +540,7 @@ public static IPAddress BitwiseAnd( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static (IPAddress Address, int Subnet) BitwiseAnd( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(BitwiseAnd))); /// @@ -556,7 +556,7 @@ public static (IPAddress Address, int Subnet) BitwiseAnd( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static PhysicalAddress BitwiseAnd( - [CanBeNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) + [NotNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(BitwiseAnd))); /// @@ -572,7 +572,7 @@ public static PhysicalAddress BitwiseAnd( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static IPAddress BitwiseOr( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(BitwiseOr))); /// @@ -588,7 +588,7 @@ public static IPAddress BitwiseOr( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static (IPAddress Address, int Subnet) BitwiseOr( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(BitwiseOr))); /// @@ -604,7 +604,7 @@ public static (IPAddress Address, int Subnet) BitwiseOr( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static PhysicalAddress BitwiseOr( - [CanBeNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) + [NotNull] this DbFunctions _, [NotNull] PhysicalAddress macaddr, [NotNull] PhysicalAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(BitwiseOr))); #endregion @@ -623,7 +623,7 @@ public static PhysicalAddress BitwiseOr( /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static IPAddress Add([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, int value) + public static IPAddress Add([NotNull] this DbFunctions _, [NotNull] IPAddress inet, int value) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Add))); /// @@ -638,7 +638,7 @@ public static IPAddress Add([CanBeNull] this DbFunctions _, [NotNull] IPAddress /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static (IPAddress Address, int Subnet) Add([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, int value) + public static (IPAddress Address, int Subnet) Add([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, int value) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Add))); /// @@ -653,7 +653,7 @@ public static (IPAddress Address, int Subnet) Add([CanBeNull] this DbFunctions _ /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static IPAddress Subtract([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, int value) + public static IPAddress Subtract([NotNull] this DbFunctions _, [NotNull] IPAddress inet, int value) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Subtract))); /// @@ -669,7 +669,7 @@ public static IPAddress Subtract([CanBeNull] this DbFunctions _, [NotNull] IPAdd /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static (IPAddress Address, int Subnet) Subtract( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, int value) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, int value) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Subtract))); /// @@ -684,7 +684,7 @@ public static (IPAddress Address, int Subnet) Subtract( /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static int Subtract([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + public static int Subtract([NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Subtract))); /// @@ -700,7 +700,7 @@ public static int Subtract([CanBeNull] this DbFunctions _, [NotNull] IPAddress i /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static int Subtract( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Subtract))); #endregion @@ -718,7 +718,7 @@ public static int Subtract( /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static string Abbreviate([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet) + public static string Abbreviate([NotNull] this DbFunctions _, [NotNull] IPAddress inet) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Abbreviate))); /// @@ -732,7 +732,7 @@ public static string Abbreviate([CanBeNull] this DbFunctions _, [NotNull] IPAddr /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static string Abbreviate([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) + public static string Abbreviate([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Abbreviate))); /// @@ -746,7 +746,7 @@ public static string Abbreviate([CanBeNull] this DbFunctions _, (IPAddress Addre /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static IPAddress Broadcast([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet) + public static IPAddress Broadcast([NotNull] this DbFunctions _, [NotNull] IPAddress inet) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Broadcast))); /// @@ -760,7 +760,7 @@ public static IPAddress Broadcast([CanBeNull] this DbFunctions _, [NotNull] IPAd /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static IPAddress Broadcast([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) + public static IPAddress Broadcast([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Broadcast))); /// @@ -774,7 +774,7 @@ public static IPAddress Broadcast([CanBeNull] this DbFunctions _, (IPAddress Add /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static int Family([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet) + public static int Family([NotNull] this DbFunctions _, [NotNull] IPAddress inet) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Family))); /// @@ -788,7 +788,7 @@ public static int Family([CanBeNull] this DbFunctions _, [NotNull] IPAddress ine /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static int Family([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) + public static int Family([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Family))); /// @@ -802,7 +802,7 @@ public static int Family([CanBeNull] this DbFunctions _, (IPAddress Address, int /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static string Host([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet) + public static string Host([NotNull] this DbFunctions _, [NotNull] IPAddress inet) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Host))); /// @@ -816,7 +816,7 @@ public static string Host([CanBeNull] this DbFunctions _, [NotNull] IPAddress in /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static string Host([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) + public static string Host([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Host))); /// @@ -830,7 +830,7 @@ public static string Host([CanBeNull] this DbFunctions _, (IPAddress Address, in /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static IPAddress HostMask([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet) + public static IPAddress HostMask([NotNull] this DbFunctions _, [NotNull] IPAddress inet) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(HostMask))); /// @@ -844,7 +844,7 @@ public static IPAddress HostMask([CanBeNull] this DbFunctions _, [NotNull] IPAdd /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static IPAddress HostMask([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) + public static IPAddress HostMask([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(HostMask))); /// @@ -858,7 +858,7 @@ public static IPAddress HostMask([CanBeNull] this DbFunctions _, (IPAddress Addr /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static int MaskLength([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet) + public static int MaskLength([NotNull] this DbFunctions _, [NotNull] IPAddress inet) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(MaskLength))); /// @@ -872,7 +872,7 @@ public static int MaskLength([CanBeNull] this DbFunctions _, [NotNull] IPAddress /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static int MaskLength([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) + public static int MaskLength([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(MaskLength))); /// @@ -886,7 +886,7 @@ public static int MaskLength([CanBeNull] this DbFunctions _, (IPAddress Address, /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static IPAddress Netmask([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet) + public static IPAddress Netmask([NotNull] this DbFunctions _, [NotNull] IPAddress inet) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Netmask))); /// @@ -900,7 +900,7 @@ public static IPAddress Netmask([CanBeNull] this DbFunctions _, [NotNull] IPAddr /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static IPAddress Netmask([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) + public static IPAddress Netmask([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Netmask))); /// @@ -914,7 +914,7 @@ public static IPAddress Netmask([CanBeNull] this DbFunctions _, (IPAddress Addre /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static (IPAddress Address, int Subnet) Network([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet) + public static (IPAddress Address, int Subnet) Network([NotNull] this DbFunctions _, [NotNull] IPAddress inet) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Network))); /// @@ -929,7 +929,7 @@ public static (IPAddress Address, int Subnet) Network([CanBeNull] this DbFunctio /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static (IPAddress Address, int Subnet) Network( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Network))); /// @@ -944,7 +944,7 @@ public static (IPAddress Address, int Subnet) Network( /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static IPAddress SetMaskLength([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, int length) + public static IPAddress SetMaskLength([NotNull] this DbFunctions _, [NotNull] IPAddress inet, int length) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(SetMaskLength))); /// @@ -960,7 +960,7 @@ public static IPAddress SetMaskLength([CanBeNull] this DbFunctions _, [NotNull] /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static (IPAddress Address, int Subnet) SetMaskLength( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, int length) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, int length) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(SetMaskLength))); /// @@ -974,7 +974,7 @@ public static (IPAddress Address, int Subnet) SetMaskLength( /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static string Text([CanBeNull] this DbFunctions _, [NotNull] IPAddress inet) + public static string Text([NotNull] this DbFunctions _, [NotNull] IPAddress inet) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Text))); /// @@ -988,7 +988,7 @@ public static string Text([CanBeNull] this DbFunctions _, [NotNull] IPAddress in /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static string Text([CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) + public static string Text([NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Text))); /// @@ -1004,7 +1004,7 @@ public static string Text([CanBeNull] this DbFunctions _, (IPAddress Address, in /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool SameFamily( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(SameFamily))); /// @@ -1020,7 +1020,7 @@ public static bool SameFamily( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static bool SameFamily( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(SameFamily))); /// @@ -1036,7 +1036,7 @@ public static bool SameFamily( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static (IPAddress Address, int Subnet) Merge( - [CanBeNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) + [NotNull] this DbFunctions _, [NotNull] IPAddress inet, [NotNull] IPAddress other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Merge))); /// @@ -1052,7 +1052,7 @@ public static (IPAddress Address, int Subnet) Merge( /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// public static (IPAddress Address, int Subnet) Merge( - [CanBeNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) + [NotNull] this DbFunctions _, (IPAddress Address, int Subnet) cidr, (IPAddress Address, int Subnet) other) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Merge))); /// @@ -1066,7 +1066,7 @@ public static (IPAddress Address, int Subnet) Merge( /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static PhysicalAddress Truncate([CanBeNull] this DbFunctions _, [NotNull] PhysicalAddress macAddress) + public static PhysicalAddress Truncate([NotNull] this DbFunctions _, [NotNull] PhysicalAddress macAddress) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Truncate))); /// @@ -1080,7 +1080,7 @@ public static PhysicalAddress Truncate([CanBeNull] this DbFunctions _, [NotNull] /// /// This method is only intended for use via SQL translation as part of an EF Core LINQ query. /// - public static PhysicalAddress Set7BitMac8([CanBeNull] this DbFunctions _, [NotNull] PhysicalAddress macAddress) + public static PhysicalAddress Set7BitMac8([NotNull] this DbFunctions _, [NotNull] PhysicalAddress macAddress) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Set7BitMac8))); #endregion diff --git a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlTrigramsDbFunctionsExtensions.cs b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlTrigramsDbFunctionsExtensions.cs index f95cea61da..2de5f132bd 100644 --- a/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlTrigramsDbFunctionsExtensions.cs +++ b/src/EFCore.PG/Extensions/DbFunctionsExtensions/NpgsqlTrigramsDbFunctionsExtensions.cs @@ -16,7 +16,7 @@ public static class NpgsqlTrigramsDbFunctionsExtensions /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static string[] TrigramsShow([CanBeNull] this DbFunctions _, [NotNull] string text) + public static string[] TrigramsShow([NotNull] this DbFunctions _, [NotNull] string text) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsShow))); /// @@ -29,7 +29,7 @@ public static string[] TrigramsShow([CanBeNull] this DbFunctions _, [NotNull] st /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static double TrigramsSimilarity([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static double TrigramsSimilarity([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsSimilarity))); /// @@ -42,7 +42,7 @@ public static double TrigramsSimilarity([CanBeNull] this DbFunctions _, [NotNull /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static double TrigramsWordSimilarity([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static double TrigramsWordSimilarity([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsWordSimilarity))); /// @@ -55,7 +55,7 @@ public static double TrigramsWordSimilarity([CanBeNull] this DbFunctions _, [Not /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static double TrigramsStrictWordSimilarity([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static double TrigramsStrictWordSimilarity([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsStrictWordSimilarity))); /// @@ -67,7 +67,7 @@ public static double TrigramsStrictWordSimilarity([CanBeNull] this DbFunctions _ /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static bool TrigramsAreSimilar([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static bool TrigramsAreSimilar([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsAreSimilar))); /// @@ -80,7 +80,7 @@ public static bool TrigramsAreSimilar([CanBeNull] this DbFunctions _, [NotNull] /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static bool TrigramsAreWordSimilar([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static bool TrigramsAreWordSimilar([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsAreWordSimilar))); /// @@ -91,7 +91,7 @@ public static bool TrigramsAreWordSimilar([CanBeNull] this DbFunctions _, [NotNu /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static bool TrigramsAreNotWordSimilar([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static bool TrigramsAreNotWordSimilar([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsAreNotWordSimilar))); /// @@ -105,7 +105,7 @@ public static bool TrigramsAreNotWordSimilar([CanBeNull] this DbFunctions _, [No /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static bool TrigramsAreStrictWordSimilar([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static bool TrigramsAreStrictWordSimilar([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsAreStrictWordSimilar))); /// @@ -116,7 +116,7 @@ public static bool TrigramsAreStrictWordSimilar([CanBeNull] this DbFunctions _, /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static bool TrigramsAreNotStrictWordSimilar([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static bool TrigramsAreNotStrictWordSimilar([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsAreNotStrictWordSimilar))); /// @@ -127,7 +127,7 @@ public static bool TrigramsAreNotStrictWordSimilar([CanBeNull] this DbFunctions /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static double TrigramsSimilarityDistance([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static double TrigramsSimilarityDistance([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsSimilarityDistance))); /// @@ -138,7 +138,7 @@ public static double TrigramsSimilarityDistance([CanBeNull] this DbFunctions _, /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static double TrigramsWordSimilarityDistance([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static double TrigramsWordSimilarityDistance([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsWordSimilarityDistance))); /// @@ -149,7 +149,7 @@ public static double TrigramsWordSimilarityDistance([CanBeNull] this DbFunctions /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static double TrigramsWordSimilarityDistanceInverted([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static double TrigramsWordSimilarityDistanceInverted([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsWordSimilarityDistanceInverted))); /// @@ -160,7 +160,7 @@ public static double TrigramsWordSimilarityDistanceInverted([CanBeNull] this DbF /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static double TrigramsStrictWordSimilarityDistance([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static double TrigramsStrictWordSimilarityDistance([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsStrictWordSimilarityDistance))); /// @@ -171,7 +171,7 @@ public static double TrigramsStrictWordSimilarityDistance([CanBeNull] this DbFun /// /// See https://www.postgresql.org/docs/current/pgtrgm.html. /// - public static double TrigramsStrictWordSimilarityDistanceInverted([CanBeNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) + public static double TrigramsStrictWordSimilarityDistanceInverted([NotNull] this DbFunctions _, [NotNull] string source, [NotNull] string target) => throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(TrigramsStrictWordSimilarityDistanceInverted))); } } diff --git a/src/EFCore.PG/Extensions/MemberInfoExtensions.cs b/src/EFCore.PG/Extensions/MemberInfoExtensions.cs index 164d251c98..1ffb9a8ea9 100644 --- a/src/EFCore.PG/Extensions/MemberInfoExtensions.cs +++ b/src/EFCore.PG/Extensions/MemberInfoExtensions.cs @@ -8,70 +8,22 @@ namespace System.Reflection internal static class EntityFrameworkMemberInfoExtensions { public static Type GetMemberType(this MemberInfo memberInfo) - => (memberInfo as PropertyInfo)?.PropertyType ?? ((FieldInfo)memberInfo)?.FieldType; + => (memberInfo as PropertyInfo)?.PropertyType ?? ((FieldInfo)memberInfo).FieldType; - public static bool IsSameAs(this MemberInfo propertyInfo, MemberInfo otherPropertyInfo) + public static bool IsSameAs(this MemberInfo? propertyInfo, MemberInfo? otherPropertyInfo) => propertyInfo == null ? otherPropertyInfo == null - : (otherPropertyInfo == null - ? false - : Equals(propertyInfo, otherPropertyInfo) - || (propertyInfo.Name == otherPropertyInfo.Name - && (propertyInfo.DeclaringType == otherPropertyInfo.DeclaringType - || propertyInfo.DeclaringType.GetTypeInfo().IsSubclassOf(otherPropertyInfo.DeclaringType) - || otherPropertyInfo.DeclaringType.GetTypeInfo().IsSubclassOf(propertyInfo.DeclaringType) - || propertyInfo.DeclaringType.GetTypeInfo().ImplementedInterfaces.Contains(otherPropertyInfo.DeclaringType) - || otherPropertyInfo.DeclaringType.GetTypeInfo().ImplementedInterfaces.Contains(propertyInfo.DeclaringType)))); - - public static MemberInfo OnInterface(this MemberInfo targetMember, Type interfaceType) - { - var declaringType = targetMember.DeclaringType; - if (declaringType == interfaceType - || declaringType.IsInterface - || !declaringType.GetInterfaces().Any(i => i == interfaceType)) - { - return targetMember; - } - - if (targetMember is MethodInfo targetMethod) - { - return targetMethod.OnInterface(interfaceType); - } - - if (targetMember is PropertyInfo targetProperty) - { - var targetGetMethod = targetProperty.GetMethod; - var interfaceGetMethod = targetGetMethod.OnInterface(interfaceType); - if (interfaceGetMethod == targetGetMethod) - { - return targetProperty; - } - - return interfaceType.GetProperties().First(p => Equals(p.GetMethod, interfaceGetMethod)); - } - - Debug.Fail("Unexpected member type: " + targetMember.MemberType); - - return targetMember; - } - - public static MethodInfo OnInterface(this MethodInfo targetMethod, Type interfaceType) - { - var declaringType = targetMethod.DeclaringType; - if (declaringType == interfaceType - || declaringType.IsInterface - || !declaringType.GetInterfaces().Any(i => i == interfaceType)) - { - return targetMethod; - } - - var map = targetMethod.DeclaringType.GetInterfaceMap(interfaceType); - var index = map.TargetMethods.IndexOf(targetMethod, MemberInfoComparer.Instance); - - return index != -1 - ? map.InterfaceMethods[index] - : targetMethod; - } + : (otherPropertyInfo != null + && (Equals(propertyInfo, otherPropertyInfo) + || (propertyInfo.Name == otherPropertyInfo.Name + && propertyInfo.DeclaringType != null + && otherPropertyInfo.DeclaringType != null + && (propertyInfo.DeclaringType == otherPropertyInfo.DeclaringType + || propertyInfo.DeclaringType.GetTypeInfo().IsSubclassOf(otherPropertyInfo.DeclaringType) + || otherPropertyInfo.DeclaringType.GetTypeInfo().IsSubclassOf(propertyInfo.DeclaringType) + || propertyInfo.DeclaringType.GetTypeInfo().ImplementedInterfaces.Contains(otherPropertyInfo.DeclaringType) + || otherPropertyInfo.DeclaringType.GetTypeInfo().ImplementedInterfaces + .Contains(propertyInfo.DeclaringType))))); public static string GetSimpleMemberName(this MemberInfo member) { @@ -79,29 +31,5 @@ public static string GetSimpleMemberName(this MemberInfo member) var index = name.LastIndexOf('.'); return index >= 0 ? name.Substring(index + 1) : name; } - - sealed class MemberInfoComparer : IEqualityComparer - { - public static readonly MemberInfoComparer Instance = new(); - - public bool Equals(MemberInfo x, MemberInfo y) - => x.IsSameAs(y); - - public int GetHashCode(MemberInfo obj) - => obj.GetHashCode(); - } - - static int IndexOf(this IEnumerable source, T item, IEqualityComparer comparer) - => source.Select( - (x, index) => - comparer.Equals(item, x) ? index : -1) - .FirstOr(x => x != -1, -1); - - static T FirstOr(this IEnumerable source, T alternate) - => source.DefaultIfEmpty(alternate).First(); - - static T FirstOr(this IEnumerable source, Func predicate, T alternate) - => source.Where(predicate).FirstOr(alternate); - } } diff --git a/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlEntityTypeExtensions.cs b/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlEntityTypeExtensions.cs index 82a291ee23..a2b94a0184 100644 --- a/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlEntityTypeExtensions.cs +++ b/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlEntityTypeExtensions.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; @@ -16,19 +17,19 @@ public static class NpgsqlEntityTypeExtensions { #region Storage parameters - public static Dictionary GetStorageParameters([NotNull] this IReadOnlyEntityType entityType) + public static Dictionary GetStorageParameters([NotNull] this IReadOnlyEntityType entityType) => entityType.GetAnnotations() - .Where(a => a.Name.StartsWith(NpgsqlAnnotationNames.StorageParameterPrefix)) + .Where(a => a.Name.StartsWith(NpgsqlAnnotationNames.StorageParameterPrefix, StringComparison.Ordinal)) .ToDictionary( a => a.Name.Substring(NpgsqlAnnotationNames.StorageParameterPrefix.Length), a => a.Value ); - public static string GetStorageParameter([NotNull] this IEntityType entityType, [NotNull] string parameterName) + public static string? GetStorageParameter([NotNull] this IEntityType entityType, [NotNull] string parameterName) { Check.NotEmpty(parameterName, nameof(parameterName)); - return (string)entityType[NpgsqlAnnotationNames.StorageParameterPrefix + parameterName]; + return (string?)entityType[NpgsqlAnnotationNames.StorageParameterPrefix + parameterName]; } public static void SetStorageParameter( diff --git a/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlIndexExtensions.cs b/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlIndexExtensions.cs index 9e59f7e7b6..f109896306 100644 --- a/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlIndexExtensions.cs +++ b/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlIndexExtensions.cs @@ -22,8 +22,8 @@ public static class NpgsqlIndexExtensions /// /// http://www.postgresql.org/docs/current/static/sql-createindex.html /// - public static string GetMethod([NotNull] this IReadOnlyIndex index) - => (string)index[NpgsqlAnnotationNames.IndexMethod]; + public static string? GetMethod([NotNull] this IReadOnlyIndex index) + => (string?)index[NpgsqlAnnotationNames.IndexMethod]; /// /// Sets the index method to be used, or null if it hasn't been specified. @@ -32,7 +32,7 @@ public static string GetMethod([NotNull] this IReadOnlyIndex index) /// /// http://www.postgresql.org/docs/current/static/sql-createindex.html /// - public static void SetMethod([NotNull] this IMutableIndex index, [CanBeNull] string method) + public static void SetMethod([NotNull] this IMutableIndex index, [CanBeNull] string? method) => index.SetOrRemoveAnnotation(NpgsqlAnnotationNames.IndexMethod, method); /// @@ -42,9 +42,9 @@ public static void SetMethod([NotNull] this IMutableIndex index, [CanBeNull] str /// /// http://www.postgresql.org/docs/current/static/sql-createindex.html /// - public static string SetMethod( + public static string? SetMethod( [NotNull] this IConventionIndex index, - [CanBeNull] string method, + [CanBeNull] string? method, bool fromDataAnnotation = false) { Check.NullButNotEmpty(method, nameof(method)); @@ -72,8 +72,8 @@ public static string SetMethod( /// /// https://www.postgresql.org/docs/current/static/indexes-opclass.html /// - public static IReadOnlyList GetOperators([NotNull] this IReadOnlyIndex index) - => (IReadOnlyList)index[NpgsqlAnnotationNames.IndexOperators]; + public static IReadOnlyList? GetOperators([NotNull] this IReadOnlyIndex index) + => (IReadOnlyList?)index[NpgsqlAnnotationNames.IndexOperators]; /// /// Sets the column operators to be used, or null if they have not been specified. @@ -81,7 +81,7 @@ public static IReadOnlyList GetOperators([NotNull] this IReadOnlyIndex i /// /// https://www.postgresql.org/docs/current/static/indexes-opclass.html /// - public static void SetOperators([NotNull] this IMutableIndex index, [CanBeNull] IReadOnlyList operators) + public static void SetOperators([NotNull] this IMutableIndex index, [CanBeNull] IReadOnlyList? operators) => index.SetOrRemoveAnnotation(NpgsqlAnnotationNames.IndexOperators, operators); /// @@ -90,9 +90,9 @@ public static void SetOperators([NotNull] this IMutableIndex index, [CanBeNull] /// /// https://www.postgresql.org/docs/current/static/indexes-opclass.html /// - public static IReadOnlyList SetOperators( + public static IReadOnlyList? SetOperators( [NotNull] this IConventionIndex index, - [CanBeNull] IReadOnlyList operators, + [CanBeNull] IReadOnlyList? operators, bool fromDataAnnotation = false) { Check.NullButNotEmpty(operators, nameof(operators)); @@ -121,8 +121,8 @@ public static IReadOnlyList SetOperators( /// https://www.postgresql.org/docs/current/static/indexes-collations.html /// #pragma warning disable 618 - public static IReadOnlyList GetCollation([NotNull] this IReadOnlyIndex index) - => (IReadOnlyList)( + public static IReadOnlyList? GetCollation([NotNull] this IReadOnlyIndex index) + => (IReadOnlyList?)( index[RelationalAnnotationNames.Collation] ?? index[NpgsqlAnnotationNames.IndexCollation]); #pragma warning restore 618 @@ -132,7 +132,7 @@ public static IReadOnlyList GetCollation([NotNull] this IReadOnlyIndex i /// /// https://www.postgresql.org/docs/current/static/indexes-collations.html /// - public static void SetCollation([NotNull] this IMutableIndex index, [CanBeNull] IReadOnlyList collations) + public static void SetCollation([NotNull] this IMutableIndex index, [CanBeNull] IReadOnlyList? collations) => index.SetOrRemoveAnnotation(RelationalAnnotationNames.Collation, collations); /// @@ -141,9 +141,9 @@ public static void SetCollation([NotNull] this IMutableIndex index, [CanBeNull] /// /// https://www.postgresql.org/docs/current/static/indexes-collations.html /// - public static IReadOnlyList SetCollation( + public static IReadOnlyList? SetCollation( [NotNull] this IConventionIndex index, - [CanBeNull] IReadOnlyList collations, + [CanBeNull] IReadOnlyList? collations, bool fromDataAnnotation = false) { Check.NullButNotEmpty(collations, nameof(collations)); @@ -171,8 +171,8 @@ public static IReadOnlyList SetCollation( /// /// https://www.postgresql.org/docs/current/static/indexes-ordering.html /// - public static IReadOnlyList GetSortOrder([NotNull] this IReadOnlyIndex index) - => (IReadOnlyList)index[NpgsqlAnnotationNames.IndexSortOrder]; + public static IReadOnlyList? GetSortOrder([NotNull] this IReadOnlyIndex index) + => (IReadOnlyList?)index[NpgsqlAnnotationNames.IndexSortOrder]; /// /// Sets the column sort orders to be used, or null if they have not been specified. @@ -180,7 +180,7 @@ public static IReadOnlyList GetSortOrder([NotNull] this IReadOnlyInde /// /// https://www.postgresql.org/docs/current/static/indexes-ordering.html /// - public static void SetSortOrder([NotNull] this IMutableIndex index, [CanBeNull] IReadOnlyList sortOrder) + public static void SetSortOrder([NotNull] this IMutableIndex index, [CanBeNull] IReadOnlyList? sortOrder) => index.SetOrRemoveAnnotation(NpgsqlAnnotationNames.IndexSortOrder, sortOrder); /// @@ -189,9 +189,9 @@ public static void SetSortOrder([NotNull] this IMutableIndex index, [CanBeNull] /// /// https://www.postgresql.org/docs/current/static/indexes-ordering.html /// - public static IReadOnlyList SetSortOrder( + public static IReadOnlyList? SetSortOrder( [NotNull] this IConventionIndex index, - [CanBeNull] IReadOnlyList sortOrder, + [CanBeNull] IReadOnlyList? sortOrder, bool fromDataAnnotation = false) { Check.NullButNotEmpty(sortOrder, nameof(sortOrder)); @@ -219,8 +219,8 @@ public static IReadOnlyList SetSortOrder( /// /// https://www.postgresql.org/docs/current/static/indexes-ordering.html /// - public static IReadOnlyList GetNullSortOrder([NotNull] this IReadOnlyIndex index) - => (IReadOnlyList)index[NpgsqlAnnotationNames.IndexNullSortOrder]; + public static IReadOnlyList? GetNullSortOrder([NotNull] this IReadOnlyIndex index) + => (IReadOnlyList?)index[NpgsqlAnnotationNames.IndexNullSortOrder]; /// /// Sets the column NULL sort orders to be used, or null if they have not been specified. @@ -228,7 +228,7 @@ public static IReadOnlyList GetNullSortOrder([NotNull] this IRead /// /// https://www.postgresql.org/docs/current/static/indexes-ordering.html /// - public static void SetNullSortOrder([NotNull] this IMutableIndex index, [CanBeNull] IReadOnlyList nullSortOrder) + public static void SetNullSortOrder([NotNull] this IMutableIndex index, [CanBeNull] IReadOnlyList? nullSortOrder) => index.SetOrRemoveAnnotation(NpgsqlAnnotationNames.IndexNullSortOrder, nullSortOrder); /// @@ -237,9 +237,9 @@ public static void SetNullSortOrder([NotNull] this IMutableIndex index, [CanBeNu /// /// https://www.postgresql.org/docs/current/static/indexes-ordering.html /// - public static IReadOnlyList SetNullSortOrder( + public static IReadOnlyList? SetNullSortOrder( [NotNull] this IConventionIndex index, - [CanBeNull] IReadOnlyList nullSortOrder, + [CanBeNull] IReadOnlyList? nullSortOrder, bool fromDataAnnotation = false) { Check.NullButNotEmpty(nullSortOrder, nameof(nullSortOrder)); @@ -266,15 +266,15 @@ public static IReadOnlyList SetNullSortOrder( /// /// The index. /// The included property names, or null if they have not been specified. - public static IReadOnlyList GetIncludeProperties([NotNull] this IReadOnlyIndex index) - => (IReadOnlyList)index[NpgsqlAnnotationNames.IndexInclude]; + public static IReadOnlyList? GetIncludeProperties([NotNull] this IReadOnlyIndex index) + => (IReadOnlyList?)index[NpgsqlAnnotationNames.IndexInclude]; /// /// Sets included property names. /// /// The index. /// The value to set. - public static void SetIncludeProperties([NotNull] this IMutableIndex index, [NotNull] IReadOnlyList properties) + public static void SetIncludeProperties([NotNull] this IMutableIndex index, [CanBeNull] IReadOnlyList? properties) => index.SetOrRemoveAnnotation( NpgsqlAnnotationNames.IndexInclude, properties); @@ -285,9 +285,9 @@ public static void SetIncludeProperties([NotNull] this IMutableIndex index, [Not /// The index. /// Indicates whether the configuration was specified using a data annotation. /// The value to set. - public static IReadOnlyList SetIncludeProperties( + public static IReadOnlyList? SetIncludeProperties( [NotNull] this IConventionIndex index, - [NotNull] IReadOnlyList properties, + [CanBeNull] IReadOnlyList? properties, bool fromDataAnnotation = false) { Check.NullButNotEmpty(properties, nameof(properties)); @@ -362,8 +362,8 @@ public static void SetIsCreatedConcurrently([NotNull] this IMutableIndex index, /// /// https://www.postgresql.org/docs/current/textsearch-tables.html#TEXTSEARCH-TABLES-INDEX /// - public static string GetTsVectorConfig([NotNull] this IReadOnlyIndex index) - => (string)index[NpgsqlAnnotationNames.TsVectorConfig]; + public static string? GetTsVectorConfig([NotNull] this IReadOnlyIndex index) + => (string?)index[NpgsqlAnnotationNames.TsVectorConfig]; /// /// Sets the text search configuration for this tsvector expression index, or null if this is not a @@ -382,7 +382,7 @@ public static string GetTsVectorConfig([NotNull] this IReadOnlyIndex index) /// /// https://www.postgresql.org/docs/current/textsearch-tables.html#TEXTSEARCH-TABLES-INDEX /// - public static void SetTsVectorConfig([NotNull] this IMutableIndex index, [CanBeNull] string config) + public static void SetTsVectorConfig([NotNull] this IMutableIndex index, [CanBeNull] string? config) => index.SetOrRemoveAnnotation(NpgsqlAnnotationNames.TsVectorConfig, config); /// @@ -402,9 +402,9 @@ public static void SetTsVectorConfig([NotNull] this IMutableIndex index, [CanBeN /// /// https://www.postgresql.org/docs/current/textsearch-tables.html#TEXTSEARCH-TABLES-INDEX /// - public static string SetTsVectorConfig( + public static string? SetTsVectorConfig( [NotNull] this IConventionIndex index, - [CanBeNull] string config, + [CanBeNull] string? config, bool fromDataAnnotation = false) { Check.NullButNotEmpty(config, nameof(config)); diff --git a/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlModelExtensions.cs b/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlModelExtensions.cs index c2ae95e5c2..3c37c659e6 100644 --- a/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlModelExtensions.cs +++ b/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlModelExtensions.cs @@ -21,7 +21,7 @@ public static class NpgsqlModelExtensions /// The model. /// The name to use for the default hi-lo sequence. public static string GetHiLoSequenceName([NotNull] this IReadOnlyModel model) - => (string)model[NpgsqlAnnotationNames.HiLoSequenceName] + => (string?)model[NpgsqlAnnotationNames.HiLoSequenceName] ?? DefaultHiLoSequenceName; /// @@ -29,7 +29,7 @@ public static string GetHiLoSequenceName([NotNull] this IReadOnlyModel model) /// /// The model. /// The value to set. - public static void SetHiLoSequenceName([NotNull] this IMutableModel model, [CanBeNull] string name) + public static void SetHiLoSequenceName([NotNull] this IMutableModel model, [CanBeNull] string? name) { Check.NullButNotEmpty(name, nameof(name)); @@ -42,8 +42,8 @@ public static void SetHiLoSequenceName([NotNull] this IMutableModel model, [CanB /// The model. /// The value to set. /// Indicates whether the configuration was specified using a data annotation. - public static string SetHiLoSequenceName( - [NotNull] this IConventionModel model, [CanBeNull] string name, bool fromDataAnnotation = false) + public static string? SetHiLoSequenceName( + [NotNull] this IConventionModel model, [CanBeNull] string? name, bool fromDataAnnotation = false) { Check.NullButNotEmpty(name, nameof(name)); @@ -66,15 +66,15 @@ public static string SetHiLoSequenceName( /// /// The model. /// The schema to use for the default hi-lo sequence. - public static string GetHiLoSequenceSchema([NotNull] this IReadOnlyModel model) - => (string)model[NpgsqlAnnotationNames.HiLoSequenceSchema]; + public static string? GetHiLoSequenceSchema([NotNull] this IReadOnlyModel model) + => (string?)model[NpgsqlAnnotationNames.HiLoSequenceSchema]; /// /// Sets the schema to use for the default hi-lo sequence. /// /// The model. /// The value to set. - public static void SetHiLoSequenceSchema([NotNull] this IMutableModel model, [CanBeNull] string value) + public static void SetHiLoSequenceSchema([NotNull] this IMutableModel model, [CanBeNull] string? value) { Check.NullButNotEmpty(value, nameof(value)); @@ -87,8 +87,8 @@ public static void SetHiLoSequenceSchema([NotNull] this IMutableModel model, [Ca /// The model. /// The value to set. /// Indicates whether the configuration was specified using a data annotation. - public static string SetHiLoSequenceSchema( - [NotNull] this IConventionModel model, [CanBeNull] string value, bool fromDataAnnotation = false) + public static string? SetHiLoSequenceSchema( + [NotNull] this IConventionModel model, [CanBeNull] string? value, bool fromDataAnnotation = false) { Check.NullButNotEmpty(value, nameof(value)); @@ -159,9 +159,9 @@ public static void SetValueGenerationStrategy([NotNull] this IMutableModel model [NotNull] public static PostgresExtension GetOrAddPostgresExtension( [NotNull] this IMutableModel model, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, - [CanBeNull] string version) + [CanBeNull] string? version) => PostgresExtension.GetOrAddPostgresExtension(model, schema, name, version); public static IReadOnlyList GetPostgresExtensions([NotNull] this IReadOnlyModel model) @@ -173,7 +173,7 @@ public static IReadOnlyList GetPostgresExtensions([NotNull] t public static PostgresEnum GetOrAddPostgresEnum( [NotNull] this IMutableModel model, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, [NotNull] string[] labels) => PostgresEnum.GetOrAddPostgresEnum(model, schema, name, labels); @@ -187,13 +187,13 @@ public static IReadOnlyList GetPostgresEnums([NotNull] this IReadO public static PostgresRange GetOrAddPostgresRange( [NotNull] this IMutableModel model, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, [NotNull] string subtype, - [CanBeNull] string canonicalFunction = null, - [CanBeNull] string subtypeOpClass = null, - [CanBeNull] string collation = null, - [CanBeNull] string subtypeDiff = null) + [CanBeNull] string? canonicalFunction = null, + [CanBeNull] string? subtypeOpClass = null, + [CanBeNull] string? collation = null, + [CanBeNull] string? subtypeDiff = null) => PostgresRange.GetOrAddPostgresRange( model, schema, @@ -211,10 +211,10 @@ public static IReadOnlyList PostgresRanges([NotNull] this IReadOn #region Database Template - public static string GetDatabaseTemplate([NotNull] this IReadOnlyModel model) - => (string)model[NpgsqlAnnotationNames.DatabaseTemplate]; + public static string? GetDatabaseTemplate([NotNull] this IReadOnlyModel model) + => (string?)model[NpgsqlAnnotationNames.DatabaseTemplate]; - public static void SetDatabaseTemplate([NotNull] this IMutableModel model, [CanBeNull] string template) + public static void SetDatabaseTemplate([NotNull] this IMutableModel model, [CanBeNull] string? template) => model.SetOrRemoveAnnotation(NpgsqlAnnotationNames.DatabaseTemplate, template); public static string SetDatabaseTemplate( @@ -236,15 +236,15 @@ public static string SetDatabaseTemplate( #region Tablespace - public static string GetTablespace([NotNull] this IReadOnlyModel model) - => (string)model[NpgsqlAnnotationNames.Tablespace]; + public static string? GetTablespace([NotNull] this IReadOnlyModel model) + => (string?)model[NpgsqlAnnotationNames.Tablespace]; - public static void SetTablespace([NotNull] this IMutableModel model, [CanBeNull] string tablespace) + public static void SetTablespace([NotNull] this IMutableModel model, [CanBeNull] string? tablespace) => model.SetOrRemoveAnnotation(NpgsqlAnnotationNames.Tablespace, tablespace); - public static string SetTablespace( + public static string? SetTablespace( [NotNull] this IConventionModel model, - [CanBeNull] string tablespace, + [CanBeNull] string? tablespace, bool fromDataAnnotation = false) { Check.NullButNotEmpty(tablespace, nameof(tablespace)); @@ -263,11 +263,11 @@ public static string SetTablespace( public static PostgresCollation GetOrAddCollation( [NotNull] this IMutableModel model, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, - [CanBeNull] string lcCollate = null, - [CanBeNull] string lcCtype = null, - [CanBeNull] string provider = null, + [NotNull] string lcCollate, + [NotNull] string lcCtype, + [CanBeNull] string? provider = null, bool? deterministic = null) => PostgresCollation.GetOrAddCollation( model, @@ -299,8 +299,8 @@ public static IReadOnlyList GetCollations([NotNull] this IRea /// For more information, see https://www.postgresql.org/docs/current/collation.html. ///

/// - public static string GetDefaultColumnCollation([NotNull] this IReadOnlyModel model) - => (string)model[NpgsqlAnnotationNames.DefaultColumnCollation]; + public static string? GetDefaultColumnCollation([NotNull] this IReadOnlyModel model) + => (string?)model[NpgsqlAnnotationNames.DefaultColumnCollation]; /// /// Sets the default collation for all columns in the database, or null if none is defined. @@ -316,7 +316,7 @@ public static string GetDefaultColumnCollation([NotNull] this IReadOnlyModel mod /// For more information, see https://www.postgresql.org/docs/current/collation.html. ///

/// - public static void SetDefaultColumnCollation([NotNull] this IMutableModel model, [CanBeNull] string collation) + public static void SetDefaultColumnCollation([NotNull] this IMutableModel model, [CanBeNull] string? collation) => model.SetOrRemoveAnnotation(NpgsqlAnnotationNames.DefaultColumnCollation, collation); /// @@ -333,7 +333,7 @@ public static void SetDefaultColumnCollation([NotNull] this IMutableModel model, /// For more information, see https://www.postgresql.org/docs/current/collation.html. ///

/// - public static string SetDefaultColumnCollation([NotNull] this IConventionModel model, [CanBeNull] string collation, bool fromDataAnnotation = false) + public static string? SetDefaultColumnCollation([NotNull] this IConventionModel model, [CanBeNull] string? collation, bool fromDataAnnotation = false) { model.SetOrRemoveAnnotation(NpgsqlAnnotationNames.DefaultColumnCollation, collation, fromDataAnnotation); return collation; diff --git a/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlPropertyExtensions.cs b/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlPropertyExtensions.cs index afbac6c2f9..c9f21154b9 100644 --- a/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlPropertyExtensions.cs +++ b/src/EFCore.PG/Extensions/MetadataExtensions/NpgsqlPropertyExtensions.cs @@ -21,8 +21,8 @@ public static class NpgsqlPropertyExtensions ///
/// The property. /// The name to use for the hi-lo sequence. - public static string GetHiLoSequenceName([NotNull] this IReadOnlyProperty property) - => (string)property[NpgsqlAnnotationNames.HiLoSequenceName]; + public static string? GetHiLoSequenceName([NotNull] this IReadOnlyProperty property) + => (string?)property[NpgsqlAnnotationNames.HiLoSequenceName]; /// /// Returns the name to use for the hi-lo sequence. @@ -30,12 +30,12 @@ public static string GetHiLoSequenceName([NotNull] this IReadOnlyProperty proper /// The property. /// The identifier of the store object. /// The name to use for the hi-lo sequence. - public static string GetHiLoSequenceName([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject) + public static string? GetHiLoSequenceName([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject) { var annotation = property.FindAnnotation(NpgsqlAnnotationNames.HiLoSequenceName); if (annotation != null) { - return (string)annotation.Value; + return (string?)annotation.Value; } var sharedTableRootProperty = property.FindSharedStoreObjectRootProperty(storeObject); @@ -49,7 +49,7 @@ public static string GetHiLoSequenceName([NotNull] this IReadOnlyProperty proper /// /// The property. /// The sequence name to use. - public static void SetHiLoSequenceName([NotNull] this IMutableProperty property, [CanBeNull] string name) + public static void SetHiLoSequenceName([NotNull] this IMutableProperty property, [CanBeNull] string? name) => property.SetOrRemoveAnnotation( NpgsqlAnnotationNames.HiLoSequenceName, Check.NullButNotEmpty(name, nameof(name))); @@ -60,9 +60,9 @@ public static void SetHiLoSequenceName([NotNull] this IMutableProperty property, /// The property. /// The sequence name to use. /// Indicates whether the configuration was specified using a data annotation. - public static string SetHiLoSequenceName( + public static string? SetHiLoSequenceName( [NotNull] this IConventionProperty property, - [CanBeNull] string name, + [CanBeNull] string? name, bool fromDataAnnotation = false) { property.SetOrRemoveAnnotation( @@ -86,8 +86,8 @@ public static string SetHiLoSequenceName( ///
/// The property. /// The schema to use for the hi-lo sequence. - public static string GetHiLoSequenceSchema([NotNull] this IReadOnlyProperty property) - => (string)property[NpgsqlAnnotationNames.HiLoSequenceSchema]; + public static string? GetHiLoSequenceSchema([NotNull] this IReadOnlyProperty property) + => (string?)property[NpgsqlAnnotationNames.HiLoSequenceSchema]; /// /// Returns the schema to use for the hi-lo sequence. @@ -95,12 +95,12 @@ public static string GetHiLoSequenceSchema([NotNull] this IReadOnlyProperty prop /// The property. /// The identifier of the store object. /// The schema to use for the hi-lo sequence. - public static string GetHiLoSequenceSchema([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject) + public static string? GetHiLoSequenceSchema([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject) { var annotation = property.FindAnnotation(NpgsqlAnnotationNames.HiLoSequenceSchema); if (annotation != null) { - return (string)annotation.Value; + return (string?)annotation.Value; } var sharedTableRootProperty = property.FindSharedStoreObjectRootProperty(storeObject); @@ -114,7 +114,7 @@ public static string GetHiLoSequenceSchema([NotNull] this IReadOnlyProperty prop /// /// The property. /// The schema to use. - public static void SetHiLoSequenceSchema([NotNull] this IMutableProperty property, [CanBeNull] string schema) + public static void SetHiLoSequenceSchema([NotNull] this IMutableProperty property, [CanBeNull] string? schema) => property.SetOrRemoveAnnotation( NpgsqlAnnotationNames.HiLoSequenceSchema, Check.NullButNotEmpty(schema, nameof(schema))); @@ -125,8 +125,8 @@ public static void SetHiLoSequenceSchema([NotNull] this IMutableProperty propert /// The property. /// The schema to use. /// Indicates whether the configuration was specified using a data annotation. - public static string SetHiLoSequenceSchema( - [NotNull] this IConventionProperty property, [CanBeNull] string schema, bool fromDataAnnotation = false) + public static string? SetHiLoSequenceSchema( + [NotNull] this IConventionProperty property, [CanBeNull] string? schema, bool fromDataAnnotation = false) { property.SetOrRemoveAnnotation( NpgsqlAnnotationNames.HiLoSequenceSchema, @@ -149,7 +149,7 @@ public static string SetHiLoSequenceSchema( ///
/// The property. /// The sequence to use, or if no sequence exists in the model. - public static IReadOnlySequence FindHiLoSequence([NotNull] this IReadOnlyProperty property) + public static IReadOnlySequence? FindHiLoSequence([NotNull] this IReadOnlyProperty property) { var model = property.DeclaringEntityType.Model; @@ -168,7 +168,7 @@ public static IReadOnlySequence FindHiLoSequence([NotNull] this IReadOnlyPropert /// The property. /// The identifier of the store object. /// The sequence to use, or if no sequence exists in the model. - public static IReadOnlySequence FindHiLoSequence([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject) + public static IReadOnlySequence? FindHiLoSequence([NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject) { var model = property.DeclaringEntityType.Model; @@ -186,8 +186,8 @@ public static IReadOnlySequence FindHiLoSequence([NotNull] this IReadOnlyPropert ///
/// The property. /// The sequence to use, or if no sequence exists in the model. - public static ISequence FindHiLoSequence([NotNull] this IProperty property) - => (ISequence)((IReadOnlyProperty)property).FindHiLoSequence(); + public static ISequence? FindHiLoSequence([NotNull] this IProperty property) + => (ISequence?)((IReadOnlyProperty)property).FindHiLoSequence(); /// /// Finds the in the model to use for the hi-lo pattern. @@ -195,8 +195,8 @@ public static ISequence FindHiLoSequence([NotNull] this IProperty property) /// The property. /// The identifier of the store object. /// The sequence to use, or if no sequence exists in the model. - public static ISequence FindHiLoSequence([NotNull] this IProperty property, in StoreObjectIdentifier storeObject) - => (ISequence)((IReadOnlyProperty)property).FindHiLoSequence(storeObject); + public static ISequence? FindHiLoSequence([NotNull] this IProperty property, in StoreObjectIdentifier storeObject) + => (ISequence?)((IReadOnlyProperty)property).FindHiLoSequence(storeObject); /// /// Removes all identity sequence annotations from the property. @@ -261,7 +261,7 @@ public static NpgsqlValueGenerationStrategy GetValueGenerationStrategy( internal static NpgsqlValueGenerationStrategy GetValueGenerationStrategy( [NotNull] this IReadOnlyProperty property, in StoreObjectIdentifier storeObject, - ITypeMappingSource typeMappingSource) + ITypeMappingSource? typeMappingSource) { if (property[NpgsqlAnnotationNames.ValueGenerationStrategy] is object annotation) return (NpgsqlValueGenerationStrategy)annotation; @@ -317,7 +317,7 @@ static NpgsqlValueGenerationStrategy GetDefaultValueGenerationStrategy(IReadOnly private static NpgsqlValueGenerationStrategy GetDefaultValueGenerationStrategy( IReadOnlyProperty property, in StoreObjectIdentifier storeObject, - ITypeMappingSource typeMappingSource) + ITypeMappingSource? typeMappingSource) { var modelStrategy = property.DeclaringEntityType.Model.GetValueGenerationStrategy(); @@ -418,7 +418,7 @@ public static bool IsCompatibleWithValueGeneration([NotNull] IReadOnlyProperty p private static bool IsCompatibleWithValueGeneration( [NotNull] IReadOnlyProperty property, in StoreObjectIdentifier storeObject, - ITypeMappingSource typeMappingSource) + ITypeMappingSource? typeMappingSource) { var type = property.ClrType; @@ -732,8 +732,8 @@ public static void RemoveIdentityOptions([NotNull] this IConventionProperty prop /// See https://www.postgresql.org/docs/current/textsearch-controls.html for more information. /// /// - public static string GetTsVectorConfig([NotNull] this IReadOnlyProperty property) - => (string)property[NpgsqlAnnotationNames.TsVectorConfig]; + public static string? GetTsVectorConfig([NotNull] this IReadOnlyProperty property) + => (string?)property[NpgsqlAnnotationNames.TsVectorConfig]; /// /// Sets the text search configuration for this generated tsvector property, or null if this is not a @@ -749,7 +749,7 @@ public static string GetTsVectorConfig([NotNull] this IReadOnlyProperty property /// See https://www.postgresql.org/docs/current/textsearch-controls.html for more information. /// /// - public static void SetTsVectorConfig([NotNull] this IMutableProperty property, [CanBeNull] string config) + public static void SetTsVectorConfig([NotNull] this IMutableProperty property, [CanBeNull] string? config) { Check.NullButNotEmpty(config, nameof(config)); @@ -796,8 +796,8 @@ public static string SetTsVectorConfig( /// /// The property. /// The included property names, or null if this is not a Generated tsvector column. - public static IReadOnlyList GetTsVectorProperties([NotNull] this IReadOnlyProperty property) - => (string[])property[NpgsqlAnnotationNames.TsVectorProperties]; + public static IReadOnlyList? GetTsVectorProperties([NotNull] this IReadOnlyProperty property) + => (string[]?)property[NpgsqlAnnotationNames.TsVectorProperties]; /// /// Sets the properties included in this generated tsvector property, or null to make this a regular, @@ -807,7 +807,7 @@ public static IReadOnlyList GetTsVectorProperties([NotNull] this IReadOn /// The included property names. public static void SetTsVectorProperties( [NotNull] this IMutableProperty property, - [CanBeNull] IReadOnlyList properties) + [CanBeNull] IReadOnlyList? properties) { Check.NullButNotEmpty(properties, nameof(properties)); @@ -821,9 +821,9 @@ public static void SetTsVectorProperties( /// The property. /// Indicates whether the configuration was specified using a data annotation. /// The included property names. - public static IReadOnlyList SetTsVectorProperties( + public static IReadOnlyList? SetTsVectorProperties( [NotNull] this IConventionProperty property, - [CanBeNull] IReadOnlyList properties, + [CanBeNull] IReadOnlyList? properties, bool fromDataAnnotation = false) { Check.NullButNotEmpty(properties, nameof(properties)); @@ -852,7 +852,7 @@ public static IReadOnlyList SetTsVectorProperties( /// /// The property. /// The collation for the column this property is mapped to. - public static string GetDefaultCollation([NotNull] this IReadOnlyProperty property) + public static string? GetDefaultCollation([NotNull] this IReadOnlyProperty property) => property.FindTypeMapping() is StringTypeMapping ? property.DeclaringEntityType.Model.GetDefaultColumnCollation() : null; diff --git a/src/EFCore.PG/Extensions/NpgsqlAlterDatabaseOperationAnnotations.cs b/src/EFCore.PG/Extensions/NpgsqlAlterDatabaseOperationAnnotations.cs index ef38d37d96..d838ef104c 100644 --- a/src/EFCore.PG/Extensions/NpgsqlAlterDatabaseOperationAnnotations.cs +++ b/src/EFCore.PG/Extensions/NpgsqlAlterDatabaseOperationAnnotations.cs @@ -55,9 +55,9 @@ public static IReadOnlyList GetOldPostgresRanges([NotNull] this A [NotNull] public static PostgresExtension GetOrAddPostgresExtension( [NotNull] this AlterDatabaseOperation operation, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, - [CanBeNull] string version) + [CanBeNull] string? version) => PostgresExtension.GetOrAddPostgresExtension(operation, schema, name, version); } } diff --git a/src/EFCore.PG/Extensions/NpgsqlDatabaseModelExtensions.cs b/src/EFCore.PG/Extensions/NpgsqlDatabaseModelExtensions.cs index 9a0b51431c..fb2aae081a 100644 --- a/src/EFCore.PG/Extensions/NpgsqlDatabaseModelExtensions.cs +++ b/src/EFCore.PG/Extensions/NpgsqlDatabaseModelExtensions.cs @@ -12,9 +12,9 @@ public static class NpgsqlDatabaseModelExtensions [NotNull] public static PostgresExtension GetOrAddPostgresExtension( [NotNull] this DatabaseModel model, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, - [CanBeNull] string version) + [CanBeNull] string? version) => PostgresExtension.GetOrAddPostgresExtension(model, schema, name, version); [NotNull] diff --git a/src/EFCore.PG/Extensions/NpgsqlDbContextOptionsBuilderExtensions.cs b/src/EFCore.PG/Extensions/NpgsqlDbContextOptionsBuilderExtensions.cs index 3600088ce8..9fa5a24818 100644 --- a/src/EFCore.PG/Extensions/NpgsqlDbContextOptionsBuilderExtensions.cs +++ b/src/EFCore.PG/Extensions/NpgsqlDbContextOptionsBuilderExtensions.cs @@ -32,7 +32,7 @@ public static class NpgsqlDbContextOptionsBuilderExtensions /// The options builder so that further configuration can be chained. public static DbContextOptionsBuilder UseNpgsql( [NotNull] this DbContextOptionsBuilder optionsBuilder, - [CanBeNull] Action npgsqlOptionsAction = null) + [CanBeNull] Action? npgsqlOptionsAction = null) { Check.NotNull(optionsBuilder, nameof(optionsBuilder)); @@ -58,7 +58,7 @@ public static DbContextOptionsBuilder UseNpgsql( public static DbContextOptionsBuilder UseNpgsql( [NotNull] this DbContextOptionsBuilder optionsBuilder, [NotNull] string connectionString, - [CanBeNull] Action npgsqlOptionsAction = null) + [CanBeNull] Action? npgsqlOptionsAction = null) { Check.NotNull(optionsBuilder, nameof(optionsBuilder)); Check.NotEmpty(connectionString, nameof(connectionString)); @@ -90,7 +90,7 @@ public static DbContextOptionsBuilder UseNpgsql( public static DbContextOptionsBuilder UseNpgsql( [NotNull] this DbContextOptionsBuilder optionsBuilder, [NotNull] DbConnection connection, - [CanBeNull] Action npgsqlOptionsAction = null) + [CanBeNull] Action? npgsqlOptionsAction = null) { Check.NotNull(optionsBuilder, nameof(optionsBuilder)); Check.NotNull(connection, nameof(connection)); @@ -121,7 +121,7 @@ public static DbContextOptionsBuilder UseNpgsql( /// The options builder so that further configuration can be chained. public static DbContextOptionsBuilder UseNpgsql( [NotNull] this DbContextOptionsBuilder optionsBuilder, - [CanBeNull] Action npgsqlOptionsAction = null) + [CanBeNull] Action? npgsqlOptionsAction = null) where TContext : DbContext => (DbContextOptionsBuilder)UseNpgsql( (DbContextOptionsBuilder)optionsBuilder, npgsqlOptionsAction); @@ -139,7 +139,7 @@ public static DbContextOptionsBuilder UseNpgsql( public static DbContextOptionsBuilder UseNpgsql( [NotNull] this DbContextOptionsBuilder optionsBuilder, [NotNull] string connectionString, - [CanBeNull] Action npgsqlOptionsAction = null) + [CanBeNull] Action? npgsqlOptionsAction = null) where TContext : DbContext => (DbContextOptionsBuilder)UseNpgsql( (DbContextOptionsBuilder)optionsBuilder, connectionString, npgsqlOptionsAction); @@ -161,7 +161,7 @@ public static DbContextOptionsBuilder UseNpgsql( public static DbContextOptionsBuilder UseNpgsql( [NotNull] this DbContextOptionsBuilder optionsBuilder, [NotNull] DbConnection connection, - [CanBeNull] Action npgsqlOptionsAction = null) + [CanBeNull] Action? npgsqlOptionsAction = null) where TContext : DbContext => (DbContextOptionsBuilder)UseNpgsql( (DbContextOptionsBuilder)optionsBuilder, connection, npgsqlOptionsAction); diff --git a/src/EFCore.PG/Migrations/NpgsqlMigrationBuilderExtensions.cs b/src/EFCore.PG/Extensions/NpgsqlMigrationBuilderExtensions.cs similarity index 83% rename from src/EFCore.PG/Migrations/NpgsqlMigrationBuilderExtensions.cs rename to src/EFCore.PG/Extensions/NpgsqlMigrationBuilderExtensions.cs index f7504d49a4..fd6d3abe2e 100644 --- a/src/EFCore.PG/Migrations/NpgsqlMigrationBuilderExtensions.cs +++ b/src/EFCore.PG/Extensions/NpgsqlMigrationBuilderExtensions.cs @@ -17,16 +17,13 @@ public static class NpgsqlMigrationBuilderExtensions /// . /// True if Npgsql is being used; false otherwise. public static bool IsNpgsql([NotNull] this MigrationBuilder builder) - => builder.ActiveProvider.Equals( - typeof(NpgsqlMigrationBuilderExtensions).GetTypeInfo().Assembly.GetName().Name, - StringComparison.Ordinal); + => builder.ActiveProvider == typeof(NpgsqlMigrationBuilderExtensions).GetTypeInfo().Assembly.GetName().Name; public static MigrationBuilder EnsurePostgresExtension( [NotNull] this MigrationBuilder builder, [NotNull] string name, - [CanBeNull] string schema = null, - [CanBeNull] string version = null - ) + [CanBeNull] string? schema = null, + [CanBeNull] string? version = null) { Check.NotEmpty(name, nameof(name)); Check.NullButNotEmpty(schema, nameof(schema)); @@ -43,8 +40,8 @@ public static MigrationBuilder EnsurePostgresExtension( public static MigrationBuilder CreatePostgresExtension( [NotNull] this MigrationBuilder builder, [NotNull] string name, - [CanBeNull] string schema = null, - [CanBeNull] string version = null) + [CanBeNull] string? schema = null, + [CanBeNull] string? version = null) => EnsurePostgresExtension(builder, name, schema, version); [Obsolete("This no longer does anything and should be removed.")] diff --git a/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs b/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs index c934465ea6..004ca5b947 100644 --- a/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs +++ b/src/EFCore.PG/Extensions/NpgsqlServiceCollectionExtensions.cs @@ -61,7 +61,7 @@ public static IServiceCollection AddEntityFrameworkNpgsql([NotNull] this IServic new EntityFrameworkRelationalServicesBuilder(serviceCollection) .TryAdd() .TryAdd>() - .TryAdd(p => p.GetService()) + .TryAdd(p => p.GetRequiredService()) .TryAdd() .TryAdd() .TryAdd() @@ -71,7 +71,7 @@ public static IServiceCollection AddEntityFrameworkNpgsql([NotNull] this IServic .TryAdd() .TryAdd() .TryAdd() - .TryAdd(p => p.GetService()) + .TryAdd(p => p.GetRequiredService()) .TryAdd() .TryAdd() .TryAdd() @@ -84,7 +84,7 @@ public static IServiceCollection AddEntityFrameworkNpgsql([NotNull] this IServic .TryAdd() .TryAdd() .TryAdd() - .TryAdd(p => p.GetService()) + .TryAdd(p => p.GetRequiredService()) .TryAdd() .TryAdd() .TryAddProviderSpecificServices( diff --git a/src/EFCore.PG/Extensions/PropertyInfoExtensions.cs b/src/EFCore.PG/Extensions/PropertyInfoExtensions.cs index ffe2d64297..5ac4e62c58 100644 --- a/src/EFCore.PG/Extensions/PropertyInfoExtensions.cs +++ b/src/EFCore.PG/Extensions/PropertyInfoExtensions.cs @@ -8,7 +8,7 @@ namespace System.Reflection internal static class PropertyInfoExtensions { public static bool IsStatic(this PropertyInfo property) - => (property.GetMethod ?? property.SetMethod).IsStatic; + => (property.GetMethod ?? property.SetMethod)!.IsStatic; public static bool IsIndexerProperty([NotNull] this PropertyInfo propertyInfo) { diff --git a/src/EFCore.PG/Extensions/TypeExtensions.cs b/src/EFCore.PG/Extensions/TypeExtensions.cs index 14aa9143df..3f7fab4fa7 100644 --- a/src/EFCore.PG/Extensions/TypeExtensions.cs +++ b/src/EFCore.PG/Extensions/TypeExtensions.cs @@ -2,15 +2,13 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; -#nullable enable - // ReSharper disable once CheckNamespace namespace System.Reflection { internal static class TypeExtensions { - internal static bool IsGenericList(this Type type) - => type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>); + internal static bool IsGenericList(this Type? type) + => type is not null && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>); internal static bool IsArrayOrGenericList(this Type type) => type.IsArray || type.IsGenericList(); diff --git a/src/EFCore.PG/Infrastructure/Internal/NpgsqlOptionsExtension.cs b/src/EFCore.PG/Infrastructure/Internal/NpgsqlOptionsExtension.cs index 336164099c..3ea58af296 100644 --- a/src/EFCore.PG/Infrastructure/Internal/NpgsqlOptionsExtension.cs +++ b/src/EFCore.PG/Infrastructure/Internal/NpgsqlOptionsExtension.cs @@ -17,20 +17,20 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure.Internal /// public class NpgsqlOptionsExtension : RelationalOptionsExtension { - DbContextOptionsExtensionInfo _info; - [NotNull] readonly List _userRangeDefinitions; + private DbContextOptionsExtensionInfo? _info; + readonly List _userRangeDefinitions; /// /// The name of the database for administrative operations. /// [CanBeNull] - public virtual string AdminDatabase { get; private set; } + public virtual string? AdminDatabase { get; private set; } /// /// The backend version to target. /// [CanBeNull] - public virtual Version PostgresVersion { get; private set; } + public virtual Version? PostgresVersion { get; private set; } /// /// The list of range mappings specified by the user. @@ -42,19 +42,19 @@ public class NpgsqlOptionsExtension : RelationalOptionsExtension /// The specified . /// [CanBeNull] - public virtual ProvideClientCertificatesCallback ProvideClientCertificatesCallback { get; private set; } + public virtual ProvideClientCertificatesCallback? ProvideClientCertificatesCallback { get; private set; } /// /// The specified . /// [CanBeNull] - public virtual RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; private set; } + public virtual RemoteCertificateValidationCallback? RemoteCertificateValidationCallback { get; private set; } /// /// The specified . /// [CanBeNull] - public virtual ProvidePasswordCallback ProvidePasswordCallback { get; private set; } + public virtual ProvidePasswordCallback? ProvidePasswordCallback { get; private set; } /// /// True if reverse null ordering is enabled; otherwise, false. @@ -93,8 +93,8 @@ public NpgsqlOptionsExtension([NotNull] NpgsqlOptionsExtension copyFrom) : base( [NotNull] public virtual NpgsqlOptionsExtension WithUserRangeDefinition( [NotNull] string rangeName, - [CanBeNull] string schemaName = null, - [CanBeNull] string subtypeName = null) + [CanBeNull] string? schemaName = null, + [CanBeNull] string? subtypeName = null) => WithUserRangeDefinition(rangeName, schemaName, typeof(TSubtype), subtypeName); /// @@ -103,9 +103,9 @@ public virtual NpgsqlOptionsExtension WithUserRangeDefinition( [NotNull] public virtual NpgsqlOptionsExtension WithUserRangeDefinition( [NotNull] string rangeName, - [CanBeNull] string schemaName, + [CanBeNull] string? schemaName, [NotNull] Type subtypeClrType, - [CanBeNull] string subtypeName) + [CanBeNull] string? subtypeName) { Check.NotEmpty(rangeName, nameof(rangeName)); Check.NotNull(subtypeClrType, nameof(subtypeClrType)); @@ -122,7 +122,7 @@ public virtual NpgsqlOptionsExtension WithUserRangeDefinition( /// /// The name of the database for administrative operations. [NotNull] - public virtual NpgsqlOptionsExtension WithAdminDatabase([CanBeNull] string adminDatabase) + public virtual NpgsqlOptionsExtension WithAdminDatabase([CanBeNull] string? adminDatabase) { var clone = (NpgsqlOptionsExtension)Clone(); @@ -139,7 +139,7 @@ public virtual NpgsqlOptionsExtension WithAdminDatabase([CanBeNull] string admin /// A copy of the current instance with the specified PostgreSQL version. /// [NotNull] - public virtual NpgsqlOptionsExtension WithPostgresVersion([CanBeNull] Version postgresVersion) + public virtual NpgsqlOptionsExtension WithPostgresVersion([CanBeNull] Version? postgresVersion) { var clone = (NpgsqlOptionsExtension)Clone(); @@ -169,7 +169,7 @@ internal virtual NpgsqlOptionsExtension WithReverseNullOrdering(bool reverseNull /// /// The specified callback. [NotNull] - public virtual NpgsqlOptionsExtension WithProvideClientCertificatesCallback([CanBeNull] ProvideClientCertificatesCallback callback) + public virtual NpgsqlOptionsExtension WithProvideClientCertificatesCallback([CanBeNull] ProvideClientCertificatesCallback? callback) { var clone = (NpgsqlOptionsExtension)Clone(); @@ -183,7 +183,7 @@ public virtual NpgsqlOptionsExtension WithProvideClientCertificatesCallback([Can /// /// The specified callback. [NotNull] - public virtual NpgsqlOptionsExtension WithRemoteCertificateValidationCallback([CanBeNull] RemoteCertificateValidationCallback callback) + public virtual NpgsqlOptionsExtension WithRemoteCertificateValidationCallback([CanBeNull] RemoteCertificateValidationCallback? callback) { var clone = (NpgsqlOptionsExtension)Clone(); @@ -197,7 +197,7 @@ public virtual NpgsqlOptionsExtension WithRemoteCertificateValidationCallback([C ///
/// The specified callback. [NotNull] - public virtual NpgsqlOptionsExtension WithProvidePasswordCallback([CanBeNull] ProvidePasswordCallback callback) + public virtual NpgsqlOptionsExtension WithProvidePasswordCallback([CanBeNull] ProvidePasswordCallback? callback) { var clone = (NpgsqlOptionsExtension)Clone(); @@ -211,7 +211,6 @@ public virtual NpgsqlOptionsExtension WithProvidePasswordCallback([CanBeNull] Pr #region Infrastructure /// - [NotNull] protected override RelationalOptionsExtension Clone() => new NpgsqlOptionsExtension(this); /// @@ -225,7 +224,7 @@ public override DbContextOptionsExtensionInfo Info sealed class ExtensionInfo : RelationalExtensionInfo { long? _serviceProviderHash; - string _logFragment; + string? _logFragment; public ExtensionInfo(IDbContextOptionsExtension extension) : base(extension) @@ -236,7 +235,6 @@ public ExtensionInfo(IDbContextOptionsExtension extension) public override bool IsDatabaseProvider => true; - [NotNull] public override string LogFragment { get @@ -368,7 +366,7 @@ public class UserRangeDefinition : IEquatable /// (which is public unless changed on the model). ///
[CanBeNull] - public virtual string SchemaName { get; } + public virtual string? SchemaName { get; } /// /// The CLR type of the range's subtype (or element). @@ -382,13 +380,13 @@ public class UserRangeDefinition : IEquatable /// This is usually not needed - the subtype will be inferred based on . /// [CanBeNull] - public virtual string SubtypeName { get; } + public virtual string? SubtypeName { get; } public UserRangeDefinition( [NotNull] string rangeName, - [CanBeNull] string schemaName, + [CanBeNull] string? schemaName, [NotNull] Type subtypeClrType, - [CanBeNull] string subtypeName) + [CanBeNull] string? subtypeName) { RangeName = Check.NotEmpty(rangeName, nameof(rangeName)); SchemaName = schemaName; @@ -399,9 +397,9 @@ public UserRangeDefinition( public override int GetHashCode() => HashCode.Combine(RangeName, SchemaName, SubtypeClrType, SubtypeName); - public override bool Equals(object obj) => obj is UserRangeDefinition urd && Equals(urd); + public override bool Equals(object? obj) => obj is UserRangeDefinition urd && Equals(urd); - public virtual bool Equals(UserRangeDefinition other) + public virtual bool Equals(UserRangeDefinition? other) => ReferenceEquals(this, other) || !(other is null) && RangeName == other.RangeName && @@ -411,9 +409,9 @@ public virtual bool Equals(UserRangeDefinition other) public virtual void Deconstruct( [NotNull] out string rangeName, - [CanBeNull] out string schemaName, + [CanBeNull] out string? schemaName, [NotNull] out Type subtypeClrType, - [CanBeNull] out string subtypeName) + [CanBeNull] out string? subtypeName) { rangeName = RangeName; schemaName = SchemaName; diff --git a/src/EFCore.PG/Infrastructure/NpgsqlDbContextOptionsBuilder.cs b/src/EFCore.PG/Infrastructure/NpgsqlDbContextOptionsBuilder.cs index ab18799e21..92c0e73de8 100644 --- a/src/EFCore.PG/Infrastructure/NpgsqlDbContextOptionsBuilder.cs +++ b/src/EFCore.PG/Infrastructure/NpgsqlDbContextOptionsBuilder.cs @@ -64,8 +64,8 @@ public virtual NpgsqlDbContextOptionsBuilder SetPostgresVersion(int major, int m /// public virtual NpgsqlDbContextOptionsBuilder MapRange( [NotNull] string rangeName, - [CanBeNull] string schemaName = null, - [CanBeNull] string subtypeName = null) + [CanBeNull] string? schemaName = null, + [CanBeNull] string? subtypeName = null) => MapRange(rangeName, typeof(TSubtype), schemaName, subtypeName); /// @@ -88,8 +88,8 @@ public virtual NpgsqlDbContextOptionsBuilder MapRange( public virtual NpgsqlDbContextOptionsBuilder MapRange( [NotNull] string rangeName, [NotNull] Type subtypeClrType, - [CanBeNull] string schemaName = null, - [CanBeNull] string subtypeName = null) + [CanBeNull] string? schemaName = null, + [CanBeNull] string? subtypeName = null) => WithOption(e => e.WithUserRangeDefinition(rangeName, schemaName, subtypeClrType, subtypeName)); /// diff --git a/src/EFCore.PG/Internal/EnumerableMethods.cs b/src/EFCore.PG/Internal/EnumerableMethods.cs index 98601cb6e6..097d3fbb24 100644 --- a/src/EFCore.PG/Internal/EnumerableMethods.cs +++ b/src/EFCore.PG/Internal/EnumerableMethods.cs @@ -3,8 +3,6 @@ using System.Linq; using System.Reflection; -#nullable enable - namespace Npgsql.EntityFrameworkCore.PostgreSQL.Internal { internal static class EnumerableMethods diff --git a/src/EFCore.PG/Internal/NpgsqlLoggerExtensions.cs b/src/EFCore.PG/Internal/NpgsqlLoggerExtensions.cs index 119444874f..8334358074 100644 --- a/src/EFCore.PG/Internal/NpgsqlLoggerExtensions.cs +++ b/src/EFCore.PG/Internal/NpgsqlLoggerExtensions.cs @@ -9,7 +9,7 @@ public static class NpgsqlLoggerExtensions { public static void MissingSchemaWarning( [NotNull] this IDiagnosticsLogger diagnostics, - [CanBeNull] string schemaName) + [CanBeNull] string? schemaName) { var definition = NpgsqlResources.LogMissingSchema(diagnostics); @@ -21,7 +21,7 @@ public static void MissingSchemaWarning( public static void MissingTableWarning( [NotNull] this IDiagnosticsLogger diagnostics, - [CanBeNull] string tableName) + [CanBeNull] string? tableName) { var definition = NpgsqlResources.LogMissingTable(diagnostics); @@ -33,9 +33,9 @@ public static void MissingTableWarning( public static void ForeignKeyReferencesMissingPrincipalTableWarning( [NotNull] this IDiagnosticsLogger diagnostics, - [CanBeNull] string foreignKeyName, - [CanBeNull] string tableName, - [CanBeNull] string principalTableName) + [CanBeNull] string? foreignKeyName, + [CanBeNull] string? tableName, + [CanBeNull] string? principalTableName) { var definition = NpgsqlResources.LogPrincipalTableNotInSelectionSet(diagnostics); @@ -52,8 +52,8 @@ public static void ColumnFound( [NotNull] string dataTypeName, bool nullable, bool identity, - [CanBeNull] string defaultValue, - [CanBeNull] string computedValue) + [CanBeNull] string? defaultValue, + [CanBeNull] string? computedValue) { var definition = NpgsqlResources.LogFoundColumn(diagnostics); @@ -83,7 +83,7 @@ public static void CollationFound( [NotNull] string collationName, [NotNull] string lcCollate, [NotNull] string lcCtype, - [NotNull] string provider, + [CanBeNull] string? provider, bool deterministic) { var definition = NpgsqlResources.LogFoundCollation(diagnostics); @@ -109,7 +109,7 @@ public static void CollationFound( public static void UniqueConstraintFound( [NotNull] this IDiagnosticsLogger diagnostics, - [NotNull] string uniqueConstraintName, + [CanBeNull] string? uniqueConstraintName, [NotNull] string tableName) { var definition = NpgsqlResources.LogFoundUniqueConstraint(diagnostics); @@ -160,7 +160,7 @@ public static void UnsupportedColumnIndexSkippedWarning( public static void UnsupportedColumnConstraintSkippedWarning( [NotNull] this IDiagnosticsLogger diagnostics, - [NotNull] string indexName, + [CanBeNull] string? indexName, [NotNull] string tableName) { var definition = NpgsqlResources.LogUnsupportedColumnConstraintSkipped(diagnostics); diff --git a/src/EFCore.PG/Internal/NpgsqlOptions.cs b/src/EFCore.PG/Internal/NpgsqlOptions.cs index ae9743b559..d21777a8fb 100644 --- a/src/EFCore.PG/Internal/NpgsqlOptions.cs +++ b/src/EFCore.PG/Internal/NpgsqlOptions.cs @@ -14,7 +14,7 @@ public class NpgsqlOptions : INpgsqlOptions public static readonly Version DefaultPostgresVersion = new(12, 0); /// - public virtual Version PostgresVersion { get; private set; } + public virtual Version PostgresVersion { get; private set; } = null!; /// public virtual bool ReverseNullOrderingEnabled { get; private set; } diff --git a/src/EFCore.PG/Metadata/CockroachDbInterleaveInParent.cs b/src/EFCore.PG/Metadata/CockroachDbInterleaveInParent.cs index bed9cb80eb..7029a7cc1f 100644 --- a/src/EFCore.PG/Metadata/CockroachDbInterleaveInParent.cs +++ b/src/EFCore.PG/Metadata/CockroachDbInterleaveInParent.cs @@ -20,7 +20,7 @@ public class CockroachDbInterleaveInParent public CockroachDbInterleaveInParent([NotNull] IReadOnlyAnnotatable annotatable) => _annotatable = annotatable; - public virtual string ParentTableSchema + public virtual string? ParentTableSchema { get => GetData().ParentTableSchema; [param: CanBeNull] set @@ -50,18 +50,18 @@ public virtual List InterleavePrefix } } - (string ParentTableSchema, string ParentTableName, List InterleavePrefix) GetData() + (string? ParentTableSchema, string ParentTableName, List InterleavePrefix) GetData() { var str = Annotatable[AnnotationName] as string; return str == null - ? (null, null, null) + ? (null, null!, null!) : Deserialize(str); } - void SetData(string parentTableSchema, string parentTableName, List interleavePrefix) + void SetData(string? parentTableSchema, string parentTableName, List interleavePrefix) => Annotatable[AnnotationName] = Serialize(parentTableSchema, parentTableName, interleavePrefix); - static string Serialize(string parentTableSchema, string parentTableName, List interleavePrefix) + static string Serialize(string? parentTableSchema, string parentTableName, List interleavePrefix) { var builder = new StringBuilder(); @@ -81,7 +81,7 @@ static string Serialize(string parentTableSchema, string parentTableName, List InterleavePrefix) Deserialize([NotNull] string value) + internal static (string? ParentTableSchema, string ParentTableName, List InterleavePrefix) Deserialize([NotNull] string value) { Check.NotEmpty(value, nameof(value)); @@ -89,10 +89,10 @@ internal static (string ParentTableSchema, string ParentTableName, List { var position = 0; var parentTableSchema = ExtractValue(value, ref position); - var parentTableName = ExtractValue(value, ref position); + var parentTableName = ExtractValue(value, ref position)!; var interleavePrefix = new List(); while (position < value.Length - 1) - interleavePrefix.Add(ExtractValue(value, ref position)); + interleavePrefix.Add(ExtractValue(value, ref position)!); return (parentTableSchema, parentTableName, interleavePrefix); } catch (Exception ex) @@ -101,7 +101,7 @@ internal static (string ParentTableSchema, string ParentTableName, List } } - private static string ExtractValue(string value, ref int position) + private static string? ExtractValue(string value, ref int position) { position = value.IndexOf('\'', position) + 1; @@ -119,13 +119,13 @@ private static string ExtractValue(string value, ref int position) return extracted.Length == 0 ? null : extracted; } - private static void EscapeAndQuote(StringBuilder builder, object value) + private static void EscapeAndQuote(StringBuilder builder, object? value) { builder.Append("'"); if (value != null) { - builder.Append(value.ToString().Replace("'", "''")); + builder.Append(value.ToString()!.Replace("'", "''")); } builder.Append("'"); diff --git a/src/EFCore.PG/Metadata/Conventions/NpgsqlConventionSetBuilder.cs b/src/EFCore.PG/Metadata/Conventions/NpgsqlConventionSetBuilder.cs index 0d6ac0ead4..3991382681 100644 --- a/src/EFCore.PG/Metadata/Conventions/NpgsqlConventionSetBuilder.cs +++ b/src/EFCore.PG/Metadata/Conventions/NpgsqlConventionSetBuilder.cs @@ -58,21 +58,52 @@ public override ConventionSet CreateConventionSet() return conventionSet; } - [EntityFrameworkInternal] + /// + /// + /// Call this method to build a for Npgsql when using + /// the outside of . + /// + /// + /// Note that it is unusual to use this method. + /// Consider using in the normal way instead. + /// + /// + /// The convention set. public static ConventionSet Build() + { + using var serviceScope = CreateServiceScope(); + using var context = serviceScope.ServiceProvider.GetRequiredService(); + return ConventionSet.CreateConventionSet(context); + } + + /// + /// + /// Call this method to build a for Npgsql outside of . + /// + /// + /// Note that it is unusual to use this method. + /// Consider using in the normal way instead. + /// + /// + /// The convention set. + public static ModelBuilder CreateModelBuilder() + { + using var serviceScope = CreateServiceScope(); + using var context = serviceScope.ServiceProvider.GetRequiredService(); + return new ModelBuilder(ConventionSet.CreateConventionSet(context), context.GetService()); + } + + private static IServiceScope CreateServiceScope() { var serviceProvider = new ServiceCollection() .AddEntityFrameworkNpgsql() - .AddDbContext(o => o.UseNpgsql("Server=.")) + .AddDbContext( + (p, o) => + o.UseNpgsql("Server=.") + .UseInternalServiceProvider(p)) .BuildServiceProvider(); - using (var serviceScope = serviceProvider.GetRequiredService().CreateScope()) - { - using (var context = serviceScope.ServiceProvider.GetService()) - { - return ConventionSet.CreateConventionSet(context); - } - } + return serviceProvider.GetRequiredService().CreateScope(); } } } diff --git a/src/EFCore.PG/Metadata/Conventions/NpgsqlStoreGenerationConvention.cs b/src/EFCore.PG/Metadata/Conventions/NpgsqlStoreGenerationConvention.cs index b76e951697..465e7acbe6 100644 --- a/src/EFCore.PG/Metadata/Conventions/NpgsqlStoreGenerationConvention.cs +++ b/src/EFCore.PG/Metadata/Conventions/NpgsqlStoreGenerationConvention.cs @@ -39,8 +39,8 @@ public NpgsqlStoreGenerationConvention( public override void ProcessPropertyAnnotationChanged( IConventionPropertyBuilder propertyBuilder, string name, - IConventionAnnotation annotation, - IConventionAnnotation oldAnnotation, + IConventionAnnotation? annotation, + IConventionAnnotation? oldAnnotation, IConventionContext context) { if (annotation == null diff --git a/src/EFCore.PG/Metadata/Conventions/NpgsqlValueGenerationConvention.cs b/src/EFCore.PG/Metadata/Conventions/NpgsqlValueGenerationConvention.cs index 9cd149c271..cacb7b63ff 100644 --- a/src/EFCore.PG/Metadata/Conventions/NpgsqlValueGenerationConvention.cs +++ b/src/EFCore.PG/Metadata/Conventions/NpgsqlValueGenerationConvention.cs @@ -40,8 +40,8 @@ public NpgsqlValueGenerationConvention( public override void ProcessPropertyAnnotationChanged( IConventionPropertyBuilder propertyBuilder, string name, - IConventionAnnotation annotation, - IConventionAnnotation oldAnnotation, + IConventionAnnotation? annotation, + IConventionAnnotation? oldAnnotation, IConventionContext context) { if (name == NpgsqlAnnotationNames.ValueGenerationStrategy) diff --git a/src/EFCore.PG/Metadata/Internal/IdentitySequenceOptionsData.cs b/src/EFCore.PG/Metadata/Internal/IdentitySequenceOptionsData.cs index 443fc27e63..3ec7720d56 100644 --- a/src/EFCore.PG/Metadata/Internal/IdentitySequenceOptionsData.cs +++ b/src/EFCore.PG/Metadata/Internal/IdentitySequenceOptionsData.cs @@ -38,9 +38,9 @@ public virtual string Serialize() } public static IdentitySequenceOptionsData Get([NotNull] IReadOnlyAnnotatable annotatable) - => Deserialize((string)annotatable[NpgsqlAnnotationNames.IdentityOptions]); + => Deserialize((string?)annotatable[NpgsqlAnnotationNames.IdentityOptions]); - public static IdentitySequenceOptionsData Deserialize([CanBeNull] string value) + public static IdentitySequenceOptionsData Deserialize([CanBeNull] string? value) { var data = new IdentitySequenceOptionsData(); @@ -52,11 +52,11 @@ public static IdentitySequenceOptionsData Deserialize([CanBeNull] string value) // ReSharper disable PossibleInvalidOperationException var position = 0; data.StartValue = AsLong(ExtractValue(value, ref position)); - data.IncrementBy = (int)AsLong(ExtractValue(value, ref position)); + data.IncrementBy = (int)AsLong(ExtractValue(value, ref position))!; data.MinValue = AsLong(ExtractValue(value, ref position)); data.MaxValue = AsLong(ExtractValue(value, ref position)); data.IsCyclic = AsBool(ExtractValue(value, ref position)); - data.NumbersToCache = (int)AsLong(ExtractValue(value, ref position)); + data.NumbersToCache = (int)AsLong(ExtractValue(value, ref position))!; // ReSharper restore PossibleInvalidOperationException return data; @@ -67,7 +67,7 @@ public static IdentitySequenceOptionsData Deserialize([CanBeNull] string value) } } - static string ExtractValue(string value, ref int position) + static string? ExtractValue(string value, ref int position) { position = value.IndexOf('\'', position) + 1; @@ -85,25 +85,25 @@ static string ExtractValue(string value, ref int position) return extracted.Length == 0 ? null : extracted; } - static long? AsLong(string value) + static long? AsLong(string? value) => value == null ? null : (long?)long.Parse(value, CultureInfo.InvariantCulture); - static bool AsBool(string value) + static bool AsBool(string? value) => value != null && bool.Parse(value); - static void EscapeAndQuote(StringBuilder builder, object value) + static void EscapeAndQuote(StringBuilder builder, object? value) { builder.Append("'"); if (value != null) { - builder.Append(value.ToString().Replace("'", "''")); + builder.Append(value.ToString()!.Replace("'", "''")); } builder.Append("'"); } - public virtual bool Equals(IdentitySequenceOptionsData other) + public virtual bool Equals(IdentitySequenceOptionsData? other) => !(other is null) && ( ReferenceEquals(this, other) || StartValue == other.StartValue && @@ -114,7 +114,7 @@ public virtual bool Equals(IdentitySequenceOptionsData other) NumbersToCache == other.NumbersToCache ); - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj is IdentitySequenceOptionsData other && Equals(other); public override int GetHashCode() diff --git a/src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationProvider.cs b/src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationProvider.cs index fd462cedda..dfb71ad902 100644 --- a/src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationProvider.cs +++ b/src/EFCore.PG/Metadata/Internal/NpgsqlAnnotationProvider.cs @@ -87,8 +87,8 @@ public override IEnumerable For(IColumn column) yield return new Annotation( NpgsqlAnnotationNames.TsVectorProperties, - valueGeneratedProperty.GetTsVectorProperties() - .Select(p2 => valueGeneratedProperty.DeclaringEntityType.FindProperty(p2).GetColumnName(tableIdentifier)) + valueGeneratedProperty.GetTsVectorProperties()! + .Select(p2 => valueGeneratedProperty.DeclaringEntityType.FindProperty(p2)!.GetColumnName(tableIdentifier)) .ToArray()); } } @@ -118,7 +118,7 @@ public override IEnumerable For(ITableIndex index) yield return new Annotation( NpgsqlAnnotationNames.IndexInclude, includeProperties - .Select(p => modelIndex.DeclaringEntityType.FindProperty(p).GetColumnName(tableIdentifier)) + .Select(p => modelIndex.DeclaringEntityType.FindProperty(p)!.GetColumnName(tableIdentifier)) .ToArray()); } diff --git a/src/EFCore.PG/Metadata/PostgresCollation.cs b/src/EFCore.PG/Metadata/PostgresCollation.cs index 92b1d5d522..acd96782c4 100644 --- a/src/EFCore.PG/Metadata/PostgresCollation.cs +++ b/src/EFCore.PG/Metadata/PostgresCollation.cs @@ -23,11 +23,11 @@ internal PostgresCollation([NotNull] IReadOnlyAnnotatable annotatable, [NotNull] [NotNull] public static PostgresCollation GetOrAddCollation( [NotNull] IMutableAnnotatable annotatable, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, [NotNull] string lcCollate, [NotNull] string lcCtype, - [CanBeNull] string provider = null, + [CanBeNull] string? provider = null, bool? deterministic = null) { Check.NotNull(annotatable, nameof(annotatable)); @@ -49,9 +49,9 @@ public static PostgresCollation GetOrAddCollation( } [CanBeNull] - public static PostgresCollation FindCollation( + public static PostgresCollation? FindCollation( [NotNull] IReadOnlyAnnotatable annotatable, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name) { Check.NotNull(annotatable, nameof(annotatable)); @@ -64,7 +64,7 @@ public static PostgresCollation FindCollation( } [NotNull] - static string BuildAnnotationName(string schema, string name) + static string BuildAnnotationName(string? schema, string name) => schema != null ? $"{NpgsqlAnnotationNames.CollationDefinitionPrefix}{schema}.{name}" : $"{NpgsqlAnnotationNames.CollationDefinitionPrefix}{name}"; @@ -81,24 +81,24 @@ public static IEnumerable GetCollations([NotNull] IReadOnlyAn public virtual Annotatable Annotatable => (Annotatable)_annotatable; [CanBeNull] - public virtual string Schema => GetData().Schema; + public virtual string? Schema => GetData().Schema; [NotNull] - public virtual string Name => GetData().Name; + public virtual string Name => GetData().Name!; public virtual string LcCollate { - get => GetData().LcCollate; + get => GetData().LcCollate!; [param: NotNull] set => SetData(lcCollate: value); } public virtual string LcCtype { - get => GetData().LcCtype; + get => GetData().LcCtype!; [param: NotNull] set => SetData(lcCtype: value); } - public virtual string Provider + public virtual string? Provider { get => GetData().Provider; [param: CanBeNull] set => SetData(provider: value); @@ -110,20 +110,20 @@ public virtual bool? IsDeterministic set => SetData(deterministic: value); } - (string Schema, string Name, string LcCollate, string LcCtype, string Provider, bool? IsDeterministic) GetData() + (string? Schema, string? Name, string? LcCollate, string? LcCtype, string? Provider, bool? IsDeterministic) GetData() => Deserialize(Annotatable.FindAnnotation(_annotationName)); - void SetData(string lcCollate = null, string lcCtype = null, string provider = null, bool? deterministic = null) + void SetData(string? lcCollate = null, string? lcCtype = null, string? provider = null, bool? deterministic = null) => Annotatable[_annotationName] = $"{lcCollate ?? LcCollate},{lcCtype ?? LcCtype},{provider ?? Provider},{deterministic ?? IsDeterministic}"; - static (string Schema, string Name, string LcCollate, string LcCtype, string Provider, bool? IsDeterministic) - Deserialize([CanBeNull] IAnnotation annotation) + static (string? Schema, string? Name, string? LcCollate, string? LcCtype, string? Provider, bool? IsDeterministic) + Deserialize([CanBeNull] IAnnotation? annotation) { if (annotation == null || !(annotation.Value is string value) || string.IsNullOrEmpty(value)) - return (null, null, null, null, null, null); + return (null, null!, null!, null!, null, null); - var elements = value.Split(','); + string?[] elements = value.Split(','); if (elements.Length != 4) throw new ArgumentException($"Cannot parse collation annotation value: {value}"); @@ -131,9 +131,9 @@ void SetData(string lcCollate = null, string lcCtype = null, string provider = n if (elements[i] == "") elements[i] = null; - var isDeterministic = elements[3] is null - ? (bool?)null - : bool.Parse(elements[3]); + var isDeterministic = elements[3] is string isDeterminsticString + ? bool.Parse(isDeterminsticString) + : (bool?)null; // TODO: This would be a safer operation if we stored schema and name in the annotation value (see Sequence.cs). // Yes, this doesn't support dots in the schema/collation name, let somebody complain first. diff --git a/src/EFCore.PG/Metadata/PostgresEnum.cs b/src/EFCore.PG/Metadata/PostgresEnum.cs index 0d1e9cbcfd..bd853340c3 100644 --- a/src/EFCore.PG/Metadata/PostgresEnum.cs +++ b/src/EFCore.PG/Metadata/PostgresEnum.cs @@ -47,7 +47,7 @@ internal PostgresEnum([NotNull] IReadOnlyAnnotatable annotatable, [NotNull] stri [NotNull] public static PostgresEnum GetOrAddPostgresEnum( [NotNull] IMutableAnnotatable annotatable, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, [NotNull] string[] labels) { @@ -96,9 +96,9 @@ public static PostgresEnum GetOrAddPostgresEnum( /// /// [CanBeNull] - public static PostgresEnum FindPostgresEnum( + public static PostgresEnum? FindPostgresEnum( [NotNull] IReadOnlyAnnotatable annotatable, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name) { Check.NotNull(annotatable, nameof(annotatable)); @@ -111,7 +111,7 @@ public static PostgresEnum FindPostgresEnum( } [NotNull] - static string BuildAnnotationName(string schema, string name) + static string BuildAnnotationName(string? schema, string name) => schema != null ? $"{NpgsqlAnnotationNames.EnumPrefix}{schema}.{name}" : $"{NpgsqlAnnotationNames.EnumPrefix}{name}"; @@ -142,30 +142,30 @@ public static IEnumerable GetPostgresEnums([NotNull] IReadOnlyAnno /// The enum schema or null to represent the default schema. /// [CanBeNull] - public virtual string Schema => GetData().Schema; + public virtual string? Schema => GetData().Schema; /// /// The enum name. /// [NotNull] - public virtual string Name => GetData().Name; + public virtual string Name => GetData().Name!; /// /// The enum labels. /// public virtual IReadOnlyList Labels { - get => GetData().Labels; + get => GetData().Labels!; [param: NotNull] set => SetData(value); } - (string Schema, string Name, string[] Labels) GetData() + (string? Schema, string? Name, string[]? Labels) GetData() => Deserialize(Annotatable.FindAnnotation(_annotationName)); void SetData([NotNull] IEnumerable labels) => Annotatable[_annotationName] = string.Join(",", labels); - static (string Schema, string Name, string[] Labels) Deserialize([CanBeNull] IAnnotation annotation) + static (string? Schema, string? Name, string[]? Labels) Deserialize([CanBeNull] IAnnotation? annotation) { if (annotation == null || !(annotation.Value is string value) || string.IsNullOrEmpty(value)) return (null, null, null); diff --git a/src/EFCore.PG/Metadata/PostgresExtension.cs b/src/EFCore.PG/Metadata/PostgresExtension.cs index 73621abcdc..676405a647 100644 --- a/src/EFCore.PG/Metadata/PostgresExtension.cs +++ b/src/EFCore.PG/Metadata/PostgresExtension.cs @@ -46,9 +46,9 @@ internal PostgresExtension([NotNull] IReadOnlyAnnotatable annotatable, [NotNull] [NotNull] public static PostgresExtension GetOrAddPostgresExtension( [NotNull] IMutableAnnotatable annotatable, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, - [CanBeNull] string version) + [CanBeNull] string? version) { Check.NotNull(annotatable, nameof(annotatable)); Check.NullButNotEmpty(schema, nameof(schema)); @@ -77,7 +77,7 @@ public static PostgresExtension GetOrAddPostgresExtension( public static PostgresExtension GetOrAddPostgresExtension( [NotNull] IMutableAnnotatable annotatable, [NotNull] string name, - [CanBeNull] string version) + [CanBeNull] string? version) => GetOrAddPostgresExtension(annotatable, null, name, version); /// @@ -93,9 +93,9 @@ public static PostgresExtension GetOrAddPostgresExtension( /// /// [CanBeNull] - public static PostgresExtension FindPostgresExtension( + public static PostgresExtension? FindPostgresExtension( [NotNull] IReadOnlyAnnotatable annotatable, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name) { Check.NotNull(annotatable, nameof(annotatable)); @@ -108,7 +108,7 @@ public static PostgresExtension FindPostgresExtension( } [NotNull] - static string BuildAnnotationName(string schema, string name) + static string BuildAnnotationName(string? schema, string name) => schema != null ? $"{NpgsqlAnnotationNames.PostgresExtensionPrefix}{schema}.{name}" : $"{NpgsqlAnnotationNames.PostgresExtensionPrefix}{name}"; @@ -139,33 +139,33 @@ public static IEnumerable GetPostgresExtensions([NotNull] IRe /// The extension schema or null to represent the default schema. /// [CanBeNull] - public virtual string Schema => GetData().Schema; + public virtual string? Schema => GetData().Schema; /// /// The extension name. /// [NotNull] - public virtual string Name => GetData().Name; + public virtual string Name => GetData().Name!; /// /// The extension version. /// - public virtual string Version + public virtual string? Version { get => GetData().Version; [param: CanBeNull] set => SetData(value); } - (string Schema, string Name, string Version) GetData() - => Deserialize(Annotatable.FindAnnotation(_annotationName)); + (string? Schema, string? Name, string? Version) GetData() + => Deserialize(Annotatable.FindAnnotation(_annotationName)!); - void SetData([CanBeNull] string version) + void SetData([CanBeNull] string? version) { var data = GetData(); Annotatable[_annotationName] = $"{data.Schema},{data.Name},{version}"; } - static (string Schema, string Name, string Version) Deserialize([CanBeNull] IAnnotation annotation) + static (string? Schema, string? Name, string? Version) Deserialize([CanBeNull] IAnnotation? annotation) { if (annotation == null || !(annotation.Value is string value) || string.IsNullOrEmpty(value)) return (null, null, null); diff --git a/src/EFCore.PG/Metadata/PostgresRange.cs b/src/EFCore.PG/Metadata/PostgresRange.cs index 1fcfd34bf1..eb274b468d 100644 --- a/src/EFCore.PG/Metadata/PostgresRange.cs +++ b/src/EFCore.PG/Metadata/PostgresRange.cs @@ -51,13 +51,13 @@ internal PostgresRange([NotNull] IReadOnlyAnnotatable annotatable, [NotNull] str [NotNull] public static PostgresRange GetOrAddPostgresRange( [NotNull] IMutableAnnotatable annotatable, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, [NotNull] string subtype, - [CanBeNull] string canonicalFunction = null, - [CanBeNull] string subtypeOpClass = null, - [CanBeNull] string collation = null, - [CanBeNull] string subtypeDiff = null) + [CanBeNull] string? canonicalFunction = null, + [CanBeNull] string? subtypeOpClass = null, + [CanBeNull] string? collation = null, + [CanBeNull] string? subtypeDiff = null) { Check.NotNull(annotatable, nameof(annotatable)); Check.NullButNotEmpty(schema, nameof(schema)); @@ -92,9 +92,9 @@ public static PostgresRange GetOrAddPostgresRange( /// /// [CanBeNull] - public static PostgresRange FindPostgresRange( + public static PostgresRange? FindPostgresRange( [NotNull] IReadOnlyAnnotatable annotatable, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name) { Check.NotNull(annotatable, nameof(annotatable)); @@ -107,7 +107,7 @@ public static PostgresRange FindPostgresRange( } [NotNull] - static string BuildAnnotationName(string schema, string name) + static string BuildAnnotationName(string? schema, string name) => schema != null ? $"{NpgsqlAnnotationNames.RangePrefix}{schema}.{name}" : $"{NpgsqlAnnotationNames.RangePrefix}{name}"; @@ -138,27 +138,27 @@ public static IEnumerable GetPostgresRanges([NotNull] IReadOnlyAn /// The range schema or null to represent the default schema. /// [CanBeNull] - public virtual string Schema => GetData().Schema; + public virtual string? Schema => GetData().Schema; /// /// The range name. /// [NotNull] - public virtual string Name => GetData().Name; + public virtual string Name => GetData().Name!; /// /// The subtype of the range. /// public virtual string Subtype { - get => GetData().Subtype; + get => GetData().Subtype!; [param: NotNull] set => SetData(subtype: value); } /// /// The function defining a "step" in a discrete range. /// - public virtual string CanonicalFunction + public virtual string? CanonicalFunction { get => GetData().CanonicalFunction; [param: CanBeNull] set => SetData(canonicalFunction: value); @@ -167,7 +167,7 @@ public virtual string CanonicalFunction /// /// The operator class to use. /// - public virtual string SubtypeOpClass + public virtual string? SubtypeOpClass { get => GetData().SubtypeOpClass; [param: CanBeNull] set => SetData(subtypeOpClass: value); @@ -176,7 +176,7 @@ public virtual string SubtypeOpClass /// /// The collation to use. /// - public virtual string Collation + public virtual string? Collation { get => GetData().Collation; [param: CanBeNull] set => SetData(collation: value); @@ -185,26 +185,26 @@ public virtual string Collation /// /// The function defining a difference in subtype values. /// - public virtual string SubtypeDiff + public virtual string? SubtypeDiff { get => GetData().SubtypeDiff; [param: CanBeNull] set => SetData(subtypeDiff: value); } - (string Schema, string Name, string Subtype, string CanonicalFunction, string SubtypeOpClass, string Collation, string SubtypeDiff) GetData() - => Deserialize(Annotatable.FindAnnotation(_annotationName)); + (string? Schema, string? Name, string? Subtype, string? CanonicalFunction, string? SubtypeOpClass, string? Collation, string? SubtypeDiff) GetData() + => Deserialize(Annotatable.FindAnnotation(_annotationName)!); - void SetData(string subtype = null, string canonicalFunction = null, string subtypeOpClass = null, string collation = null, string subtypeDiff = null) + void SetData(string? subtype = null, string? canonicalFunction = null, string? subtypeOpClass = null, string? collation = null, string? subtypeDiff = null) => Annotatable[_annotationName] = $"{subtype ?? Subtype},{canonicalFunction ?? CanonicalFunction},{subtypeOpClass ?? SubtypeOpClass},{collation ?? Collation},{subtypeDiff ?? SubtypeDiff}"; - static (string Schema, string Name, string Subtype, string CanonicalFunction, string SubtypeOpClass, string Collation, string SubtypeDiff) - Deserialize([CanBeNull] IAnnotation annotation) + static (string? Schema, string? Name, string? Subtype, string? CanonicalFunction, string? SubtypeOpClass, string? Collation, string? SubtypeDiff) + Deserialize([CanBeNull] IAnnotation? annotation) { if (annotation == null || !(annotation.Value is string value) || string.IsNullOrEmpty(value)) return (null, null, null, null, null, null, null); - var elements = value.Split(','); + string?[] elements = value.Split(','); if (elements.Length != 5) throw new ArgumentException($"Cannot parse range annotation value: {value}"); diff --git a/src/EFCore.PG/Migrations/Internal/NpgsqlHistoryRepository.cs b/src/EFCore.PG/Migrations/Internal/NpgsqlHistoryRepository.cs index 37a59abc43..97aa51b5b3 100644 --- a/src/EFCore.PG/Migrations/Internal/NpgsqlHistoryRepository.cs +++ b/src/EFCore.PG/Migrations/Internal/NpgsqlHistoryRepository.cs @@ -40,7 +40,7 @@ protected override string ExistsSql } } - protected override bool InterpretExistsResult(object value) => (bool)value; + protected override bool InterpretExistsResult(object? value) => (bool?)value == true; public override string GetCreateIfNotExistsScript() { diff --git a/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs b/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs index 567342c1a7..e1a422a9fa 100644 --- a/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs +++ b/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs @@ -21,12 +21,12 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Migrations { public class NpgsqlMigrationsSqlGenerator : MigrationsSqlGenerator { - readonly RelationalTypeMapping _stringTypeMapping; + private readonly RelationalTypeMapping _stringTypeMapping; /// /// The backend version to target. /// - readonly Version _postgresVersion; + private readonly Version _postgresVersion; public NpgsqlMigrationsSqlGenerator( [NotNull] MigrationsSqlGeneratorDependencies dependencies, @@ -40,7 +40,7 @@ public NpgsqlMigrationsSqlGenerator( public override IReadOnlyList Generate( IReadOnlyList operations, - IModel model = null, + IModel? model = null, MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default) { var results = base.Generate(operations, model, options); @@ -70,7 +70,7 @@ public override IReadOnlyList Generate( { t.Schema, t.Table, - Column = p, + Column = p!, })) .ToArray(); @@ -84,7 +84,7 @@ public override IReadOnlyList Generate( // parameter string literal, but the second one is a column name that shouldn't be double-quoted... var table = Dependencies.SqlGenerationHelper.DelimitIdentifier(c.Table, c.Schema); - var column = Dependencies.SqlGenerationHelper.DelimitIdentifier(c.Column); + var column = Dependencies.SqlGenerationHelper.DelimitIdentifier(c.Column!); var unquotedColumn = c.Column.Replace("'", "''"); // When generating idempotent scripts, migration DDL is enclosed in anonymous DO blocks, @@ -115,7 +115,7 @@ public override IReadOnlyList Generate( return results; } - protected override void Generate(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder) + protected override void Generate(MigrationOperation operation, IModel? model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); @@ -139,7 +139,7 @@ protected override void Generate(MigrationOperation operation, IModel model, Mig protected override void Generate( CreateTableOperation operation, - IModel model, + IModel? model, MigrationCommandListBuilder builder, bool terminate = true) { @@ -228,7 +228,7 @@ protected override void Generate( } } - protected override void Generate(AlterTableOperation operation, IModel model, MigrationCommandListBuilder builder) + protected override void Generate(AlterTableOperation operation, IModel? model, MigrationCommandListBuilder builder) { var madeChanges = false; @@ -311,7 +311,7 @@ protected override void Generate(AlterTableOperation operation, IModel model, Mi protected override void Generate( DropColumnOperation operation, - IModel model, + IModel? model, MigrationCommandListBuilder builder, bool terminate = true) { @@ -324,7 +324,7 @@ protected override void Generate( protected override void Generate( AddColumnOperation operation, - IModel model, + IModel? model, MigrationCommandListBuilder builder, bool terminate = true) { @@ -371,7 +371,7 @@ protected override void Generate( } } - protected override void Generate(AlterColumnOperation operation, IModel model, MigrationCommandListBuilder builder) + protected override void Generate(AlterColumnOperation operation, IModel? model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); @@ -423,14 +423,14 @@ protected override void Generate(AlterColumnOperation operation, IModel model, M return; } - string newSequenceName = null; + string? newSequenceName = null; var alterBase = $"ALTER TABLE {DelimitIdentifier(operation.Table, operation.Schema)} " + $"ALTER COLUMN {DelimitIdentifier(operation.Name)} "; // TYPE + COLLATION var type = operation.ColumnType ?? - GetColumnType(operation.Schema, operation.Table, operation.Name, operation, model); + GetColumnType(operation.Schema, operation.Table, operation.Name, operation, model)!; var oldType = IsOldColumnSupported(model) ? operation.OldColumn.ColumnType ?? GetColumnType(operation.Schema, operation.Table, operation.Name, operation.OldColumn, model) @@ -439,8 +439,8 @@ protected override void Generate(AlterColumnOperation operation, IModel model, M // If a collation was defined on the column specifically, via the standard EF mechanism, it will be // available in operation.Collation (as usual). If not, there may be a model-wide default column collation, // which gets transmitted via the Npgsql-specific annotation. - var oldCollation = (string)(operation.OldColumn.Collation ?? operation.OldColumn[NpgsqlAnnotationNames.DefaultColumnCollation]); - var newCollation = (string)(operation.Collation ?? operation[NpgsqlAnnotationNames.DefaultColumnCollation]); + var oldCollation = (string?)(operation.OldColumn.Collation ?? operation.OldColumn[NpgsqlAnnotationNames.DefaultColumnCollation]); + var newCollation = (string?)(operation.Collation ?? operation[NpgsqlAnnotationNames.DefaultColumnCollation]); if (type != oldType || newCollation != oldCollation) { @@ -679,7 +679,7 @@ protected override void Generate(AlterColumnOperation operation, IModel model, M EndStatement(builder); } - protected override void Generate(RenameIndexOperation operation, IModel model, MigrationCommandListBuilder builder) + protected override void Generate(RenameIndexOperation operation, IModel? model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); @@ -694,7 +694,7 @@ protected override void Generate(RenameIndexOperation operation, IModel model, M EndStatement(builder); } - protected override void Generate(RenameSequenceOperation operation, IModel model, MigrationCommandListBuilder builder) + protected override void Generate(RenameSequenceOperation operation, IModel? model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); @@ -717,7 +717,7 @@ protected override void Generate(RenameSequenceOperation operation, IModel model EndStatement(builder); } - protected override void Generate(RenameTableOperation operation, IModel model, MigrationCommandListBuilder builder) + protected override void Generate(RenameTableOperation operation, IModel? model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); @@ -742,7 +742,7 @@ protected override void Generate(RenameTableOperation operation, IModel model, M protected override void Generate( CreateIndexOperation operation, - IModel model, + IModel? model, MigrationCommandListBuilder builder, bool terminate = true) { @@ -790,7 +790,7 @@ protected override void Generate( } } - protected override void IndexOptions(CreateIndexOperation operation, IModel model, MigrationCommandListBuilder builder) + protected override void IndexOptions(CreateIndexOperation operation, IModel? model, MigrationCommandListBuilder builder) { if (_postgresVersion.AtLeast(11) && operation[NpgsqlAnnotationNames.IndexInclude] is string[] includeColumns && @@ -805,7 +805,7 @@ operation[NpgsqlAnnotationNames.IndexInclude] is string[] includeColumns && base.IndexOptions(operation, model, builder); } - protected override void Generate(EnsureSchemaOperation operation, IModel model, MigrationCommandListBuilder builder) + protected override void Generate(EnsureSchemaOperation operation, IModel? model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); @@ -831,7 +831,7 @@ protected override void Generate(EnsureSchemaOperation operation, IModel model, protected virtual void Generate( [NotNull] NpgsqlCreateDatabaseOperation operation, - [CanBeNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); @@ -872,7 +872,7 @@ protected virtual void Generate( public virtual void Generate( [NotNull] NpgsqlDropDatabaseOperation operation, - [CanBeNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); @@ -899,11 +899,10 @@ public virtual void Generate( protected override void Generate( AlterDatabaseOperation operation, - IModel model, + IModel? model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); - Check.NotNull(model, nameof(model)); Check.NotNull(builder, nameof(builder)); if (operation.Collation != operation.OldDatabase.Collation) @@ -921,10 +920,10 @@ protected override void Generate( protected virtual void GenerateCreateExtension( [NotNull] PostgresExtension extension, - [NotNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { - var schema = extension.Schema ?? model.GetDefaultSchema(); + var schema = extension.Schema ?? model?.GetDefaultSchema(); // Schemas are normally created (or rather ensured) by the model differ, which scans all tables, sequences // and other database objects. However, it isn't aware of extensions, so we always ensure schema on enum creation. @@ -957,7 +956,7 @@ protected virtual void GenerateCreateExtension( protected virtual void GenerateCollationStatements( [NotNull] AlterDatabaseOperation operation, - [NotNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { foreach (var collationToCreate in operation.GetPostgresCollations() @@ -990,10 +989,10 @@ protected virtual void GenerateCollationStatements( protected virtual void GenerateCreateCollation( [NotNull] PostgresCollation collation, - [NotNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { - var schema = collation.Schema ?? model.GetDefaultSchema(); + var schema = collation.Schema ?? model?.GetDefaultSchema(); // Schemas are normally created (or rather ensured) by the model differ, which scans all tables, sequences // and other database objects. However, it isn't aware of collation, so we always ensure schema on collation creation. @@ -1028,10 +1027,10 @@ protected virtual void GenerateCreateCollation( protected virtual void GenerateDropCollation( [NotNull] PostgresCollation collation, - [NotNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { - var schema = collation.Schema ?? model.GetDefaultSchema(); + var schema = collation.Schema ?? model?.GetDefaultSchema(); builder .Append("DROP COLLATION ") @@ -1045,7 +1044,7 @@ protected virtual void GenerateDropCollation( protected virtual void GenerateEnumStatements( [NotNull] AlterDatabaseOperation operation, - [NotNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { foreach (var enumTypeToCreate in operation.GetPostgresEnums() @@ -1098,10 +1097,10 @@ protected virtual void GenerateEnumStatements( protected virtual void GenerateCreateEnum( [NotNull] PostgresEnum enumType, - [NotNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { - var schema = enumType.Schema ?? model.GetDefaultSchema(); + var schema = enumType.Schema ?? model?.GetDefaultSchema(); // Schemas are normally created (or rather ensured) by the model differ, which scans all tables, sequences // and other database objects. However, it isn't aware of enums, so we always ensure schema on enum creation. @@ -1126,10 +1125,10 @@ protected virtual void GenerateCreateEnum( protected virtual void GenerateDropEnum( [NotNull] PostgresEnum enumType, - [NotNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { - var schema = enumType.Schema ?? model.GetDefaultSchema(); + var schema = enumType.Schema ?? model?.GetDefaultSchema(); builder .Append("DROP TYPE ") @@ -1140,11 +1139,11 @@ protected virtual void GenerateDropEnum( protected virtual void GenerateAddEnumLabel( [NotNull] PostgresEnum enumType, [NotNull] string addedLabel, - [CanBeNull] string beforeLabel, - [NotNull] IModel model, + [CanBeNull] string? beforeLabel, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { - var schema = enumType.Schema ?? model.GetDefaultSchema(); + var schema = enumType.Schema ?? model?.GetDefaultSchema(); builder .Append("ALTER TYPE ") @@ -1172,7 +1171,7 @@ protected virtual void GenerateAddEnumLabel( protected virtual void GenerateRangeStatements( [NotNull] AlterDatabaseOperation operation, - [NotNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { foreach (var rangeTypeToCreate in operation.GetPostgresRanges() @@ -1197,10 +1196,10 @@ protected virtual void GenerateRangeStatements( protected virtual void GenerateCreateRange( [NotNull] PostgresRange rangeType, - [NotNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { - var schema = rangeType.Schema ?? model.GetDefaultSchema(); + var schema = rangeType.Schema ?? model?.GetDefaultSchema(); // Schemas are normally created (or rather ensured) by the model differ, which scans all tables, sequences // and other database objects. However, it isn't aware of ranges, so we always ensure schema on range creation. @@ -1210,7 +1209,7 @@ protected virtual void GenerateCreateRange( builder .Append("CREATE TYPE ") .Append(DelimitIdentifier(rangeType.Name, schema)) - .AppendLine($" AS RANGE (") + .AppendLine(" AS RANGE (") .IncrementIndent(); var def = new List { $"SUBTYPE = {rangeType.Subtype}" }; @@ -1235,10 +1234,10 @@ protected virtual void GenerateCreateRange( protected virtual void GenerateDropRange( [NotNull] PostgresRange rangeType, - [NotNull] IModel model, + [CanBeNull] IModel? model, [NotNull] MigrationCommandListBuilder builder) { - var schema = rangeType.Schema ?? model.GetDefaultSchema(); + var schema = rangeType.Schema ?? model?.GetDefaultSchema(); builder .Append("DROP TYPE ") @@ -1250,7 +1249,7 @@ protected virtual void GenerateDropRange( protected override void Generate( DropIndexOperation operation, - IModel model, + IModel? model, MigrationCommandListBuilder builder, bool terminate = true) { @@ -1270,7 +1269,7 @@ protected override void Generate( protected override void Generate( RenameColumnOperation operation, - IModel model, + IModel? model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); @@ -1297,7 +1296,7 @@ protected override void Generate( /// Indicates whether or not to terminate the command after generating SQL for the operation. protected override void Generate( InsertDataOperation operation, - IModel model, + IModel? model, MigrationCommandListBuilder builder, bool terminate = true) { @@ -1322,7 +1321,7 @@ protected override void Generate( builder.EndCommand(); } - protected override void Generate(CreateSequenceOperation operation, IModel model, MigrationCommandListBuilder builder) + protected override void Generate(CreateSequenceOperation operation, IModel? model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); @@ -1347,11 +1346,11 @@ protected override void Generate(CreateSequenceOperation operation, IModel model #region Utilities protected override void ColumnDefinition( - string schema, + string? schema, string table, string name, ColumnOperation operation, - IModel model, + IModel? model, MigrationCommandListBuilder builder) { Check.NotEmpty(name, nameof(name)); @@ -1405,7 +1404,7 @@ protected override void ColumnDefinition( return; } - var columnType = operation.ColumnType ?? GetColumnType(schema, table, name, operation, model); + var columnType = operation.ColumnType ?? GetColumnType(schema, table, name, operation, model)!; builder .Append(DelimitIdentifier(name)) .Append(" ") @@ -1530,11 +1529,11 @@ long Max(Type type) /// The target model which may be null if the operations exist without a model. /// The command builder to use to add the SQL fragment. protected override void ComputedColumnDefinition( - string schema, + string? schema, string table, string name, ColumnOperation operation, - IModel model, + IModel? model, MigrationCommandListBuilder builder) { Check.NotEmpty(name, nameof(name)); @@ -1554,7 +1553,7 @@ protected override void ComputedColumnDefinition( builder .Append(DelimitIdentifier(name)) .Append(" ") - .Append(operation.ColumnType ?? GetColumnType(schema, table, name, operation, model)); + .Append(operation.ColumnType ?? GetColumnType(schema, table, name, operation, model)!); if (operation.Collation != null) { @@ -1565,7 +1564,7 @@ protected override void ComputedColumnDefinition( builder .Append(" GENERATED ALWAYS AS (") - .Append(operation.ComputedColumnSql) + .Append(operation.ComputedColumnSql!) .Append(") STORED"); } @@ -1588,7 +1587,7 @@ static void CheckForOldValueGenerationAnnotation([NotNull] IAnnotatable annotata /// The type of the object (e.g. TABLE, INDEX, SEQUENCE). /// The builder to which operations are appended. public virtual void Rename( - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, [NotNull] string newName, [NotNull] string type, @@ -1619,7 +1618,7 @@ public virtual void Rename( /// The builder to which operations are appended. public virtual void Transfer( [NotNull] string newSchema, - [CanBeNull] string schema, + [CanBeNull] string? schema, [NotNull] string name, [NotNull] string type, [NotNull] MigrationCommandListBuilder builder) @@ -1664,7 +1663,7 @@ Dictionary GetStorageParameters(Annotatable annotatable) .Where(a => a.Name.StartsWith(NpgsqlAnnotationNames.StorageParameterPrefix)) .ToDictionary( a => a.Name.Substring(NpgsqlAnnotationNames.StorageParameterPrefix.Length), - a => GenerateStorageParameterValue(a.Value) + a => GenerateStorageParameterValue(a.Value!) ); static string GenerateStorageParameterValue(object value) @@ -1673,7 +1672,7 @@ static string GenerateStorageParameterValue(object value) return (bool)value ? "true" : "false"; if (value is string) return $"'{value}'"; - return value.ToString(); + return value.ToString()!; } #endregion Storage parameter utilities @@ -1683,10 +1682,10 @@ static string GenerateStorageParameterValue(object value) string DelimitIdentifier(string identifier) => Dependencies.SqlGenerationHelper.DelimitIdentifier(identifier); - string DelimitIdentifier(string name, string schema) => + string DelimitIdentifier(string name, string? schema) => Dependencies.SqlGenerationHelper.DelimitIdentifier(name, schema); - string IndexColumnList(IndexColumn[] columns, string method) + string IndexColumnList(IndexColumn[] columns, string? method) { var isFirst = true; var builder = new StringBuilder(); @@ -1742,7 +1741,7 @@ string IndexColumnList(IndexColumn[] columns, string method) return builder.ToString(); } - string ColumnsToTsVector(IEnumerable columns, string tsVectorConfig, IModel model, string schema, string table) + string ColumnsToTsVector(IEnumerable columns, string tsVectorConfig, IModel? model, string? schema, string table) { string GetTsVectorColumnExpression(string columnName) { @@ -1763,7 +1762,7 @@ string GetTsVectorColumnExpression(string columnName) .ToString(); } - static bool TryParseSchema(string identifier, out string name, out string schema) + static bool TryParseSchema(string identifier, out string name, out string? schema) { var index = identifier.IndexOf('.'); @@ -1774,12 +1773,12 @@ static bool TryParseSchema(string identifier, out string name, out string schema return true; } + name = identifier; schema = default; - name = default; return false; } - static IndexColumn[] GetIndexColumns(CreateIndexOperation operation) + private static IndexColumn[] GetIndexColumns(CreateIndexOperation operation) { var collations = operation[RelationalAnnotationNames.Collation] as string[]; @@ -1805,7 +1804,7 @@ static IndexColumn[] GetIndexColumns(CreateIndexOperation operation) readonly struct IndexColumn { - public IndexColumn(string name, string @operator, string collation, SortOrder sortOrder, NullSortOrder nullSortOrder) + public IndexColumn(string name, string? @operator, string? collation, SortOrder sortOrder, NullSortOrder nullSortOrder) { Name = name; Operator = @operator; @@ -1815,8 +1814,8 @@ public IndexColumn(string name, string @operator, string collation, SortOrder so } public string Name { get; } - public string Operator { get; } - public string Collation { get; } + public string? Operator { get; } + public string? Collation { get; } public SortOrder SortOrder { get; } public NullSortOrder NullSortOrder { get; } } diff --git a/src/EFCore.PG/Migrations/Operations/NpgsqlCreateDatabaseOperation.cs b/src/EFCore.PG/Migrations/Operations/NpgsqlCreateDatabaseOperation.cs index 394c2a8542..94824db88b 100644 --- a/src/EFCore.PG/Migrations/Operations/NpgsqlCreateDatabaseOperation.cs +++ b/src/EFCore.PG/Migrations/Operations/NpgsqlCreateDatabaseOperation.cs @@ -5,8 +5,8 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Operations { public class NpgsqlCreateDatabaseOperation : DatabaseOperation { - public virtual string Name { get; [param: NotNull] set; } - public virtual string Template { get; [param: CanBeNull] set; } - public virtual string Tablespace { get; [param: CanBeNull] set; } + public virtual string Name { get; [param: NotNull] set; } = null!; + public virtual string? Template { get; [param: CanBeNull] set; } + public virtual string? Tablespace { get; [param: CanBeNull] set; } } } diff --git a/src/EFCore.PG/Migrations/Operations/NpgsqlDropDatabaseOperation.cs b/src/EFCore.PG/Migrations/Operations/NpgsqlDropDatabaseOperation.cs index 5ce23f898d..1a9141c886 100644 --- a/src/EFCore.PG/Migrations/Operations/NpgsqlDropDatabaseOperation.cs +++ b/src/EFCore.PG/Migrations/Operations/NpgsqlDropDatabaseOperation.cs @@ -5,6 +5,6 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.Operations { public class NpgsqlDropDatabaseOperation : MigrationOperation { - public virtual string Name { get;[param: NotNull] set; } + public virtual string Name { get; [param: NotNull] set; } = null!; } } diff --git a/src/EFCore.PG/NpgsqlRetryingExecutionStrategy.cs b/src/EFCore.PG/NpgsqlRetryingExecutionStrategy.cs index ddcdc5bff9..e58a82c5c7 100644 --- a/src/EFCore.PG/NpgsqlRetryingExecutionStrategy.cs +++ b/src/EFCore.PG/NpgsqlRetryingExecutionStrategy.cs @@ -9,7 +9,7 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL { public class NpgsqlRetryingExecutionStrategy : ExecutionStrategy { - readonly ICollection _additionalErrorCodes; + readonly ICollection? _additionalErrorCodes; /// /// Creates a new instance of . @@ -69,7 +69,7 @@ public NpgsqlRetryingExecutionStrategy( [NotNull] DbContext context, int maxRetryCount, TimeSpan maxRetryDelay, - [CanBeNull] ICollection errorCodesToAdd) + [CanBeNull] ICollection? errorCodesToAdd) : base(context, maxRetryCount, maxRetryDelay) @@ -86,14 +86,14 @@ public NpgsqlRetryingExecutionStrategy( [NotNull] ExecutionStrategyDependencies dependencies, int maxRetryCount, TimeSpan maxRetryDelay, - [CanBeNull] ICollection errorCodesToAdd) + [CanBeNull] ICollection? errorCodesToAdd) : base(dependencies, maxRetryCount, maxRetryDelay) => _additionalErrorCodes = errorCodesToAdd; // TODO: Unlike SqlException, which seems to also wrap various transport/IO errors // and expose them via error codes, we have NpgsqlException with an inner exception. // Would be good to provide a way to add these into the additional list. - protected override bool ShouldRetryOn(Exception exception) + protected override bool ShouldRetryOn(Exception? exception) => exception is PostgresException postgresException && _additionalErrorCodes?.Contains(postgresException.SqlState) == true || NpgsqlTransientExceptionDetector.ShouldRetryOn(exception); diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlArrayTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlArrayTranslator.cs index da2ccbe87e..b69e96900b 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlArrayTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlArrayTranslator.cs @@ -50,8 +50,8 @@ public NpgsqlArrayTranslator( _jsonPocoTranslator = jsonPocoTranslator; } - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) @@ -89,7 +89,7 @@ static bool IsMappedToNonArray(SqlExpression arrayOrList) => arrayOrList.TypeMapping is RelationalTypeMapping typeMapping && typeMapping is not (NpgsqlArrayTypeMapping or NpgsqlJsonTypeMapping); - SqlExpression TranslateCommon(SqlExpression arrayOrList, IReadOnlyList arguments) + SqlExpression? TranslateCommon(SqlExpression arrayOrList, IReadOnlyList arguments) { // Predicate-less Any - translate to a simple length check. if (method.IsClosedFormOf(EnumerableAnyWithoutPredicate)) @@ -169,7 +169,7 @@ arrayOrList.TypeMapping is NpgsqlArrayTypeMapping or null } } - public virtual SqlExpression Translate(SqlExpression instance, + public virtual SqlExpression? Translate(SqlExpression? instance, MemberInfo member, Type returnType, IDiagnosticsLogger logger) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlByteArrayMethodTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlByteArrayMethodTranslator.cs index 9aadd3ef99..ef624eacc7 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlByteArrayMethodTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlByteArrayMethodTranslator.cs @@ -20,8 +20,8 @@ public class NpgsqlByteArrayMethodTranslator : IMethodCallTranslator public NpgsqlByteArrayMethodTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory) => _sqlExpressionFactory = sqlExpressionFactory; - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) @@ -40,7 +40,7 @@ public virtual SqlExpression Translate( // We have a byte value, but we need a bytea for PostgreSQL POSITION. var value = arguments[1] is SqlConstantExpression constantValue - ? (SqlExpression)_sqlExpressionFactory.Constant(new[] { (byte)constantValue.Value }, typeMapping) + ? (SqlExpression)_sqlExpressionFactory.Constant(new[] { (byte)constantValue.Value! }, typeMapping) // Create bytea from non-constant byte: SELECT set_byte('\x00', 0, 8::smallint); : _sqlExpressionFactory.Function( "set_byte", diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlConvertTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlConvertTranslator.cs index 43346e2d5c..a0c4b99fd9 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlConvertTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlConvertTranslator.cs @@ -54,8 +54,8 @@ static readonly List SupportedMethods public NpgsqlConvertTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory) => _sqlExpressionFactory = sqlExpressionFactory; - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlDateTimeMemberTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlDateTimeMemberTranslator.cs index 3333dc4701..8a1c4087ac 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlDateTimeMemberTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlDateTimeMemberTranslator.cs @@ -18,13 +18,14 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte /// public class NpgsqlDateTimeMemberTranslator : IMemberTranslator { - readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; public NpgsqlDateTimeMemberTranslator([NotNull] NpgsqlSqlExpressionFactory sqlExpressionFactory) => _sqlExpressionFactory = sqlExpressionFactory; /// - public virtual SqlExpression Translate(SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MemberInfo member, Type returnType, IDiagnosticsLogger logger) @@ -46,22 +47,22 @@ public virtual SqlExpression Translate(SqlExpression instance, argumentsPropagateNullability: TrueArrays[2], returnType), - nameof(DateTime.Year) => GetDatePartExpression(instance, "year"), - nameof(DateTime.Month) => GetDatePartExpression(instance, "month"), - nameof(DateTime.DayOfYear) => GetDatePartExpression(instance, "doy"), - nameof(DateTime.Day) => GetDatePartExpression(instance, "day"), - nameof(DateTime.Hour) => GetDatePartExpression(instance, "hour"), - nameof(DateTime.Minute) => GetDatePartExpression(instance, "minute"), - nameof(DateTime.Second) => GetDatePartExpression(instance, "second"), + nameof(DateTime.Year) => GetDatePartExpression(instance!, "year"), + nameof(DateTime.Month) => GetDatePartExpression(instance!, "month"), + nameof(DateTime.DayOfYear) => GetDatePartExpression(instance!, "doy"), + nameof(DateTime.Day) => GetDatePartExpression(instance!, "day"), + nameof(DateTime.Hour) => GetDatePartExpression(instance!, "hour"), + nameof(DateTime.Minute) => GetDatePartExpression(instance!, "minute"), + nameof(DateTime.Second) => GetDatePartExpression(instance!, "second"), nameof(DateTime.Millisecond) => null, // Too annoying // .NET's DayOfWeek is an enum, but its int values happen to correspond to PostgreSQL - nameof(DateTime.DayOfWeek) => GetDatePartExpression(instance, "dow", floor: true), + nameof(DateTime.DayOfWeek) => GetDatePartExpression(instance!, "dow", floor: true), nameof(DateTime.Date) => _sqlExpressionFactory.Function( "date_trunc", - new[] { _sqlExpressionFactory.Constant("day"), instance }, + new[] { _sqlExpressionFactory.Constant("day"), instance! }, nullable: true, argumentsPropagateNullability: TrueArrays[2], returnType), @@ -90,7 +91,7 @@ SqlFunctionExpression Now() /// /// Constructs the DATE_PART expression. /// - /// The member expression. + /// The member expression. /// The name of the DATE_PART to construct. /// True if the result should be wrapped with FLOOR(...); otherwise, false. /// @@ -101,7 +102,7 @@ SqlFunctionExpression Now() /// This also gets rid of sub-second components when retrieving seconds. /// [NotNull] - SqlExpression GetDatePartExpression( + private SqlExpression GetDatePartExpression( [NotNull] SqlExpression instance, [NotNull] string partName, bool floor = false) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlDateTimeMethodTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlDateTimeMethodTranslator.cs index 3174151d6e..be7d4ea14c 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlDateTimeMethodTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlDateTimeMethodTranslator.cs @@ -21,25 +21,25 @@ public class NpgsqlDateTimeMethodTranslator : IMethodCallTranslator /// [NotNull] static readonly Dictionary MethodInfoDatePartMapping = new() { - { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddYears), new[] { typeof(int) }), "years" }, - { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddMonths), new[] { typeof(int) }), "months" }, - { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddDays), new[] { typeof(double) }), "days" }, - { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddHours), new[] { typeof(double) }), "hours" }, - { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddMinutes), new[] { typeof(double) }), "mins" }, - { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddSeconds), new[] { typeof(double) }), "secs" }, - //{ typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddMilliseconds), new[] { typeof(double) }), "milliseconds" }, - { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddYears), new[] { typeof(int) }), "years" }, - { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddMonths), new[] { typeof(int) }), "months" }, - { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddDays), new[] { typeof(double) }), "days" }, - { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddHours), new[] { typeof(double) }), "hours" }, - { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddMinutes), new[] { typeof(double) }), "mins" }, - { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddSeconds), new[] { typeof(double) }), "secs" }, - //{ typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddMilliseconds), new[] { typeof(double) }), "milliseconds" } + { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddYears), new[] { typeof(int) })!, "years" }, + { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddMonths), new[] { typeof(int) })!, "months" }, + { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddDays), new[] { typeof(double) })!, "days" }, + { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddHours), new[] { typeof(double) })!, "hours" }, + { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddMinutes), new[] { typeof(double) })!, "mins" }, + { typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddSeconds), new[] { typeof(double) })!, "secs" }, + //{ typeof(DateTime).GetRuntimeMethod(nameof(DateTime.AddMilliseconds), new[] { typeof(double) })!, "milliseconds" }, + { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddYears), new[] { typeof(int) })!, "years" }, + { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddMonths), new[] { typeof(int) })!, "months" }, + { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddDays), new[] { typeof(double) })!, "days" }, + { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddHours), new[] { typeof(double) })!, "hours" }, + { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddMinutes), new[] { typeof(double) })!, "mins" }, + { typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddSeconds), new[] { typeof(double) })!, "secs" }, + //{ typeof(DateTimeOffset).GetRuntimeMethod(nameof(DateTimeOffset.AddMilliseconds), new[] { typeof(double) })!, "milliseconds" } }; - readonly ISqlExpressionFactory _sqlExpressionFactory; - readonly RelationalTypeMapping _intervalMapping; - readonly RelationalTypeMapping _textMapping; + private readonly ISqlExpressionFactory _sqlExpressionFactory; + private readonly RelationalTypeMapping _intervalMapping; + private readonly RelationalTypeMapping _textMapping; /// /// Initializes a new instance of the class. @@ -49,13 +49,13 @@ public NpgsqlDateTimeMethodTranslator( [NotNull] ISqlExpressionFactory sqlExpressionFactory) { _sqlExpressionFactory = sqlExpressionFactory; - _intervalMapping = typeMappingSource.FindMapping("interval"); - _textMapping = typeMappingSource.FindMapping("text"); + _intervalMapping = typeMappingSource.FindMapping("interval")!; + _textMapping = typeMappingSource.FindMapping("text")!; } /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) @@ -74,7 +74,7 @@ public virtual SqlExpression Translate( { // We generate constant intervals as INTERVAL '1 days' if (constantExpression.Type == typeof(double) && - ((double)constantExpression.Value >= int.MaxValue || + ((double)constantExpression.Value! >= int.MaxValue || (double)constantExpression.Value <= int.MinValue)) { return null; diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlFullTextSearchMethodTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlFullTextSearchMethodTranslator.cs index ae46ff595d..cc426ed83a 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlFullTextSearchMethodTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlFullTextSearchMethodTranslator.cs @@ -19,19 +19,19 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte /// public class NpgsqlFullTextSearchMethodTranslator : IMethodCallTranslator { - static readonly MethodInfo TsQueryParse = - typeof(NpgsqlTsQuery).GetMethod(nameof(NpgsqlTsQuery.Parse), BindingFlags.Public | BindingFlags.Static); + private static readonly MethodInfo TsQueryParse = + typeof(NpgsqlTsQuery).GetMethod(nameof(NpgsqlTsQuery.Parse), BindingFlags.Public | BindingFlags.Static)!; - static readonly MethodInfo TsVectorParse = - typeof(NpgsqlTsVector).GetMethod(nameof(NpgsqlTsVector.Parse), BindingFlags.Public | BindingFlags.Static); + private static readonly MethodInfo TsVectorParse = + typeof(NpgsqlTsVector).GetMethod(nameof(NpgsqlTsVector.Parse), BindingFlags.Public | BindingFlags.Static)!; - readonly IRelationalTypeMappingSource _typeMappingSource; - readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; - readonly RelationalTypeMapping _boolMapping; - readonly RelationalTypeMapping _tsQueryMapping; - readonly RelationalTypeMapping _tsVectorMapping; - readonly RelationalTypeMapping _regconfigMapping; - readonly RelationalTypeMapping _regdictionaryMapping; + private readonly IRelationalTypeMappingSource _typeMappingSource; + private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly RelationalTypeMapping _boolMapping; + private readonly RelationalTypeMapping _tsQueryMapping; + private readonly RelationalTypeMapping _tsVectorMapping; + private readonly RelationalTypeMapping _regconfigMapping; + private readonly RelationalTypeMapping _regdictionaryMapping; public NpgsqlFullTextSearchMethodTranslator( [NotNull] IRelationalTypeMappingSource typeMappingSource, @@ -39,16 +39,16 @@ public NpgsqlFullTextSearchMethodTranslator( { _typeMappingSource = typeMappingSource; _sqlExpressionFactory = sqlExpressionFactory; - _boolMapping = typeMappingSource.FindMapping(typeof(bool)); - _tsQueryMapping = typeMappingSource.FindMapping("tsquery"); - _tsVectorMapping = typeMappingSource.FindMapping("tsvector"); - _regconfigMapping = typeMappingSource.FindMapping("regconfig"); - _regdictionaryMapping = typeMappingSource.FindMapping("regdictionary"); + _boolMapping = typeMappingSource.FindMapping(typeof(bool))!; + _tsQueryMapping = typeMappingSource.FindMapping("tsquery")!; + _tsVectorMapping = typeMappingSource.FindMapping("tsvector")!; + _regconfigMapping = typeMappingSource.FindMapping("regconfig")!; + _regdictionaryMapping = typeMappingSource.FindMapping("regdictionary")!; } /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) @@ -128,7 +128,7 @@ public virtual SqlExpression Translate( var newArgs = new List(arguments); if (newArgs[1].Type == typeof(NpgsqlTsVector.Lexeme.Weight)) newArgs[1] = newArgs[1] is SqlConstantExpression weightExpression - ? _sqlExpressionFactory.Constant(weightExpression.Value.ToString()[0]) + ? _sqlExpressionFactory.Constant(weightExpression.Value!.ToString()![0]) : throw new ArgumentException("Enum 'weight' argument for 'SetWeight' must be a constant expression."); return _sqlExpressionFactory.Function( "setweight", @@ -278,7 +278,7 @@ arguments[1] is SqlConstantExpression constant method.ReturnType, _tsVectorMapping), - _ => (SqlExpression)null + _ => null }; } diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlFuzzyStringMatchMethodTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlFuzzyStringMatchMethodTranslator.cs index ae1042c2fb..6ff2b68e25 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlFuzzyStringMatchMethodTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlFuzzyStringMatchMethodTranslator.cs @@ -12,7 +12,7 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte { public class NpgsqlFuzzyStringMatchMethodTranslator : IMethodCallTranslator { - static readonly Dictionary Functions = new() + private static readonly Dictionary Functions = new() { [GetRuntimeMethod(nameof(NpgsqlFuzzyStringMatchDbFunctionsExtensions.FuzzyStringMatchSoundex), new[] { typeof(DbFunctions), typeof(string) })] = "soundex", [GetRuntimeMethod(nameof(NpgsqlFuzzyStringMatchDbFunctionsExtensions.FuzzyStringMatchDifference), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "difference", @@ -25,12 +25,12 @@ public class NpgsqlFuzzyStringMatchMethodTranslator : IMethodCallTranslator [GetRuntimeMethod(nameof(NpgsqlFuzzyStringMatchDbFunctionsExtensions.FuzzyStringMatchDoubleMetaphoneAlt), new[] { typeof(DbFunctions), typeof(string) })] = "dmetaphone_alt" }; - static MethodInfo GetRuntimeMethod(string name, params Type[] parameters) - => typeof(NpgsqlFuzzyStringMatchDbFunctionsExtensions).GetRuntimeMethod(name, parameters); + private static MethodInfo GetRuntimeMethod(string name, params Type[] parameters) + => typeof(NpgsqlFuzzyStringMatchDbFunctionsExtensions).GetRuntimeMethod(name, parameters)!; - readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; - static readonly bool[][] TrueArrays = + private static readonly bool[][] TrueArrays = { Array.Empty(), new[] { true }, @@ -45,8 +45,8 @@ public NpgsqlFuzzyStringMatchMethodTranslator([NotNull] NpgsqlSqlExpressionFacto => _sqlExpressionFactory = sqlExpressionFactory; /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonDbFunctionsTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonDbFunctionsTranslator.cs index 8e060d28dd..4f1f6be9ec 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonDbFunctionsTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonDbFunctionsTranslator.cs @@ -27,13 +27,13 @@ public NpgsqlJsonDbFunctionsTranslator( [NotNull] NpgsqlSqlExpressionFactory sqlExpressionFactory) { _sqlExpressionFactory = sqlExpressionFactory; - _boolTypeMapping = typeMappingSource.FindMapping(typeof(bool)); - _stringTypeMapping = typeMappingSource.FindMapping(typeof(string)); - _jsonbTypeMapping = typeMappingSource.FindMapping("jsonb"); + _boolTypeMapping = typeMappingSource.FindMapping(typeof(bool))!; + _stringTypeMapping = typeMappingSource.FindMapping(typeof(string))!; + _jsonbTypeMapping = typeMappingSource.FindMapping("jsonb")!; } - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) @@ -60,7 +60,7 @@ public virtual SqlExpression Translate( if (method.Name == nameof(NpgsqlJsonDbFunctionsExtensions.JsonTypeof)) { return _sqlExpressionFactory.Function( - ((NpgsqlJsonTypeMapping)args[0].TypeMapping).IsJsonb ? "jsonb_typeof" : "json_typeof", + ((NpgsqlJsonTypeMapping)args[0].TypeMapping!).IsJsonb ? "jsonb_typeof" : "json_typeof", new[] { args[0] }, nullable: true, argumentsPropagateNullability: TrueArrays[1], diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonDomTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonDomTranslator.cs index 2df4440c6a..5004264df8 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonDomTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonDomTranslator.cs @@ -17,15 +17,15 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte { public class NpgsqlJsonDomTranslator : IMemberTranslator, IMethodCallTranslator { - static readonly MemberInfo RootElement = typeof(JsonDocument).GetProperty(nameof(JsonDocument.RootElement)); - static readonly MethodInfo GetProperty = typeof(JsonElement).GetRuntimeMethod(nameof(JsonElement.GetProperty), new[] { typeof(string) }); - static readonly MethodInfo GetArrayLength = typeof(JsonElement).GetRuntimeMethod(nameof(JsonElement.GetArrayLength), Type.EmptyTypes); + private static readonly MemberInfo RootElement = typeof(JsonDocument).GetProperty(nameof(JsonDocument.RootElement))!; + private static readonly MethodInfo GetProperty = typeof(JsonElement).GetRuntimeMethod(nameof(JsonElement.GetProperty), new[] { typeof(string) })!; + private static readonly MethodInfo GetArrayLength = typeof(JsonElement).GetRuntimeMethod(nameof(JsonElement.GetArrayLength), Type.EmptyTypes)!; - static readonly MethodInfo ArrayIndexer = typeof(JsonElement).GetProperties() + private static readonly MethodInfo ArrayIndexer = typeof(JsonElement).GetProperties() .Single(p => p.GetIndexParameters().Length == 1 && p.GetIndexParameters()[0].ParameterType == typeof(int)) - .GetMethod; + .GetMethod!; - static readonly string[] GetMethods = + private static readonly string[] GetMethods = { nameof(JsonElement.GetBoolean), nameof(JsonElement.GetDateTime), @@ -40,9 +40,9 @@ public class NpgsqlJsonDomTranslator : IMemberTranslator, IMethodCallTranslator nameof(JsonElement.GetString) }; - readonly IRelationalTypeMappingSource _typeMappingSource; - readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; - readonly RelationalTypeMapping _stringTypeMapping; + private readonly IRelationalTypeMappingSource _typeMappingSource; + private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly RelationalTypeMapping _stringTypeMapping; public NpgsqlJsonDomTranslator( [NotNull] IRelationalTypeMappingSource typeMappingSource, @@ -50,10 +50,10 @@ public NpgsqlJsonDomTranslator( { _typeMappingSource = typeMappingSource; _sqlExpressionFactory = sqlExpressionFactory; - _stringTypeMapping = typeMappingSource.FindMapping(typeof(string)); + _stringTypeMapping = typeMappingSource.FindMapping(typeof(string))!; } - public virtual SqlExpression Translate(SqlExpression instance, + public virtual SqlExpression? Translate(SqlExpression? instance, MemberInfo member, Type returnType, IDiagnosticsLogger logger) @@ -72,14 +72,14 @@ instance is ColumnExpression column && return null; } - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) { if (method.DeclaringType != typeof(JsonElement) || - !(instance.TypeMapping is NpgsqlJsonTypeMapping mapping)) + instance?.TypeMapping is not NpgsqlJsonTypeMapping mapping) { return null; } diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonPocoTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonPocoTranslator.cs index 5fd29ae363..3488102cce 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonPocoTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlJsonPocoTranslator.cs @@ -16,9 +16,9 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte { public class NpgsqlJsonPocoTranslator : IMemberTranslator { - readonly IRelationalTypeMappingSource _typeMappingSource; - readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; - readonly RelationalTypeMapping _stringTypeMapping; + private readonly IRelationalTypeMappingSource _typeMappingSource; + private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly RelationalTypeMapping _stringTypeMapping; public NpgsqlJsonPocoTranslator( [NotNull] IRelationalTypeMappingSource typeMappingSource, @@ -26,10 +26,10 @@ public NpgsqlJsonPocoTranslator( { _typeMappingSource = typeMappingSource; _sqlExpressionFactory = sqlExpressionFactory; - _stringTypeMapping = typeMappingSource.FindMapping(typeof(string)); + _stringTypeMapping = typeMappingSource.FindMapping(typeof(string))!; } - public virtual SqlExpression Translate(SqlExpression instance, + public virtual SqlExpression? Translate(SqlExpression? instance, MemberInfo member, Type returnType, IDiagnosticsLogger logger) @@ -41,7 +41,7 @@ public virtual SqlExpression Translate(SqlExpression instance, returnType) : null; - public virtual SqlExpression TranslateMemberAccess( + public virtual SqlExpression? TranslateMemberAccess( [NotNull] SqlExpression instance, [NotNull] SqlExpression member, [NotNull] Type returnType) { // The first time we see a JSON traversal it's on a column - create a JsonTraversalExpression. @@ -70,7 +70,7 @@ public virtual SqlExpression TranslateMemberAccess( return null; } - public virtual SqlExpression TranslateArrayLength([NotNull] SqlExpression expression) + public virtual SqlExpression? TranslateArrayLength([NotNull] SqlExpression expression) { if (expression is ColumnExpression columnExpression && columnExpression.TypeMapping is NpgsqlJsonTypeMapping mapping) @@ -94,7 +94,7 @@ public virtual SqlExpression TranslateArrayLength([NotNull] SqlExpression expres lastPathComponent.Type, _typeMappingSource.FindMapping(lastPathComponent.Type)); - var jsonMapping = (NpgsqlJsonTypeMapping)traversal.Expression.TypeMapping; + var jsonMapping = (NpgsqlJsonTypeMapping)traversal.Expression.TypeMapping!; return _sqlExpressionFactory.Function( jsonMapping.IsJsonb ? "jsonb_array_length" : "json_array_length", new[] { newTraversal }, diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlLTreeTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlLTreeTranslator.cs index fadfa43cf3..09e279cb36 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlLTreeTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlLTreeTranslator.cs @@ -28,17 +28,17 @@ public class NpgsqlLTreeTranslator : IMethodCallTranslator, IMemberTranslator readonly RelationalTypeMapping _lqueryArrayTypeMapping; readonly RelationalTypeMapping _ltxtqueryTypeMapping; - static readonly MethodInfo IsAncestorOf = - typeof(LTree).GetRuntimeMethod(nameof(LTree.IsAncestorOf), new[] { typeof(LTree) }); + private static readonly MethodInfo IsAncestorOf = + typeof(LTree).GetRuntimeMethod(nameof(LTree.IsAncestorOf), new[] { typeof(LTree) })!; - static readonly MethodInfo IsDescendantOf = - typeof(LTree).GetRuntimeMethod(nameof(LTree.IsDescendantOf), new[] { typeof(LTree) }); + private static readonly MethodInfo IsDescendantOf = + typeof(LTree).GetRuntimeMethod(nameof(LTree.IsDescendantOf), new[] { typeof(LTree) })!; - static readonly MethodInfo MatchesLQuery = - typeof(LTree).GetRuntimeMethod(nameof(LTree.MatchesLQuery), new[] { typeof(string) }); + private static readonly MethodInfo MatchesLQuery = + typeof(LTree).GetRuntimeMethod(nameof(LTree.MatchesLQuery), new[] { typeof(string) })!; - static readonly MethodInfo MatchesLTxtQuery = - typeof(LTree).GetRuntimeMethod(nameof(LTree.MatchesLTxtQuery), new[] { typeof(string) }); + private static readonly MethodInfo MatchesLTxtQuery = + typeof(LTree).GetRuntimeMethod(nameof(LTree.MatchesLTxtQuery), new[] { typeof(string) })!; public NpgsqlLTreeTranslator( [NotNull] IRelationalTypeMappingSource typeMappingSource, @@ -46,17 +46,17 @@ public NpgsqlLTreeTranslator( { _typeMappingSource = typeMappingSource; _sqlExpressionFactory = sqlExpressionFactory; - _boolTypeMapping = typeMappingSource.FindMapping(typeof(bool)); - _ltreeTypeMapping = typeMappingSource.FindMapping(typeof(LTree)); - _ltreeArrayTypeMapping = typeMappingSource.FindMapping(typeof(LTree[])); - _lqueryTypeMapping = typeMappingSource.FindMapping("lquery"); - _lqueryArrayTypeMapping = typeMappingSource.FindMapping("lquery[]"); - _ltxtqueryTypeMapping = typeMappingSource.FindMapping("ltxtquery"); + _boolTypeMapping = typeMappingSource.FindMapping(typeof(bool))!; + _ltreeTypeMapping = typeMappingSource.FindMapping(typeof(LTree))!; + _ltreeArrayTypeMapping = typeMappingSource.FindMapping(typeof(LTree[]))!; + _lqueryTypeMapping = typeMappingSource.FindMapping("lquery")!; + _lqueryArrayTypeMapping = typeMappingSource.FindMapping("lquery[]")!; + _ltxtqueryTypeMapping = typeMappingSource.FindMapping("ltxtquery")!; } /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) @@ -68,7 +68,7 @@ public virtual SqlExpression Translate( nameof(LTree.IsAncestorOf) => new PostgresBinaryExpression( PostgresExpressionType.Contains, - _sqlExpressionFactory.ApplyTypeMapping(instance, _ltreeTypeMapping), + _sqlExpressionFactory.ApplyTypeMapping(instance!, _ltreeTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(arguments[0], _ltreeTypeMapping), typeof(bool), _boolTypeMapping), @@ -76,7 +76,7 @@ public virtual SqlExpression Translate( nameof(LTree.IsDescendantOf) => new PostgresBinaryExpression( PostgresExpressionType.ContainedBy, - _sqlExpressionFactory.ApplyTypeMapping(instance, _ltreeTypeMapping), + _sqlExpressionFactory.ApplyTypeMapping(instance!, _ltreeTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(arguments[0], _ltreeTypeMapping), typeof(bool), _boolTypeMapping), @@ -84,7 +84,7 @@ public virtual SqlExpression Translate( nameof(LTree.MatchesLQuery) => new PostgresBinaryExpression( PostgresExpressionType.LTreeMatches, - _sqlExpressionFactory.ApplyTypeMapping(instance, _ltreeTypeMapping), + _sqlExpressionFactory.ApplyTypeMapping(instance!, _ltreeTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(arguments[0], _lqueryTypeMapping), typeof(bool), _boolTypeMapping), @@ -92,7 +92,7 @@ public virtual SqlExpression Translate( nameof(LTree.MatchesLTxtQuery) => new PostgresBinaryExpression( PostgresExpressionType.LTreeMatches, - _sqlExpressionFactory.ApplyTypeMapping(instance, _ltreeTypeMapping), + _sqlExpressionFactory.ApplyTypeMapping(instance!, _ltreeTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(arguments[0], _ltxtqueryTypeMapping), typeof(bool), _boolTypeMapping), @@ -100,7 +100,7 @@ public virtual SqlExpression Translate( nameof(LTree.Subtree) => _sqlExpressionFactory.Function( "subltree", - new[] { instance, arguments[0], arguments[1] }, + new[] { instance!, arguments[0], arguments[1] }, nullable: true, TrueArrays[3], typeof(LTree), @@ -110,8 +110,8 @@ public virtual SqlExpression Translate( => _sqlExpressionFactory.Function( "subpath", arguments.Count == 2 - ? new[] { instance, arguments[0], arguments[1] } - : new[] { instance, arguments[0] }, + ? new[] { instance!, arguments[0], arguments[1] } + : new[] { instance!, arguments[0] }, nullable: true, arguments.Count == 2 ? TrueArrays[3] : TrueArrays[2], typeof(LTree), @@ -121,8 +121,8 @@ public virtual SqlExpression Translate( => _sqlExpressionFactory.Function( "index", arguments.Count == 2 - ? new[] { instance, arguments[0], arguments[1] } - : new[] { instance, arguments[0] }, + ? new[] { instance!, arguments[0], arguments[1] } + : new[] { instance!, arguments[0] }, nullable: true, arguments.Count == 2 ? TrueArrays[3] : TrueArrays[2], typeof(int)), @@ -143,15 +143,15 @@ public virtual SqlExpression Translate( return null; } - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MemberInfo member, Type returnType, IDiagnosticsLogger logger) => member.DeclaringType == typeof(LTree) && member.Name == nameof(LTree.NLevel) ? _sqlExpressionFactory.Function( "nlevel", - new[] { instance }, + new[] { instance! }, nullable: true, TrueArrays[1], typeof(int)) @@ -161,7 +161,7 @@ public virtual SqlExpression Translate( /// Called directly from to translate LTree array-related constructs which /// cannot be translated in regular method translators, since they require accessing lambdas. ///
- public virtual Expression VisitArrayMethodCall( + public virtual Expression? VisitArrayMethodCall( [NotNull] NpgsqlSqlTranslatingExpressionVisitor sqlTranslatingExpressionVisitor, [NotNull] MethodInfo method, [NotNull] ReadOnlyCollection arguments) @@ -174,7 +174,7 @@ arguments[1] is LambdaExpression wherePredicate && wherePredicate.Body is MethodCallExpression wherePredicateMethodCall) { var predicateMethod = wherePredicateMethodCall.Method; - var predicateInstance = wherePredicateMethodCall.Object; + var predicateInstance = wherePredicateMethodCall.Object!; var predicateArguments = wherePredicateMethodCall.Arguments; // Pattern match: new[] { "q1", "q2" }.Any(q => e.SomeLTree.MatchesLQuery(q)) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlLikeTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlLikeTranslator.cs index bddb67512a..8b6692b527 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlLikeTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlLikeTranslator.cs @@ -13,30 +13,30 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte ///
public class NpgsqlLikeTranslator : IMethodCallTranslator { - static readonly MethodInfo Like = + private static readonly MethodInfo Like = typeof(DbFunctionsExtensions).GetRuntimeMethod( nameof(DbFunctionsExtensions.Like), - new[] { typeof(DbFunctions), typeof(string), typeof(string) }); + new[] { typeof(DbFunctions), typeof(string), typeof(string) })!; - static readonly MethodInfo LikeWithEscape = + private static readonly MethodInfo LikeWithEscape = typeof(DbFunctionsExtensions).GetRuntimeMethod( nameof(DbFunctionsExtensions.Like), - new[] { typeof(DbFunctions), typeof(string), typeof(string), typeof(string) }); + new[] { typeof(DbFunctions), typeof(string), typeof(string), typeof(string) })!; // ReSharper disable once InconsistentNaming - static readonly MethodInfo ILike = + private static readonly MethodInfo ILike = typeof(NpgsqlDbFunctionsExtensions).GetRuntimeMethod( nameof(NpgsqlDbFunctionsExtensions.ILike), - new[] { typeof(DbFunctions), typeof(string), typeof(string) }); + new[] { typeof(DbFunctions), typeof(string), typeof(string) })!; // ReSharper disable once InconsistentNaming - static readonly MethodInfo ILikeWithEscape = + private static readonly MethodInfo ILikeWithEscape = typeof(NpgsqlDbFunctionsExtensions).GetRuntimeMethod( nameof(NpgsqlDbFunctionsExtensions.ILike), - new[] { typeof(DbFunctions), typeof(string), typeof(string), typeof(string) }); + new[] { typeof(DbFunctions), typeof(string), typeof(string), typeof(string) })!; [NotNull] - readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; /// /// Initializes a new instance of the class. @@ -46,8 +46,8 @@ public NpgsqlLikeTranslator([NotNull] NpgsqlSqlExpressionFactory sqlExpressionFa => _sqlExpressionFactory = sqlExpressionFactory; /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlMathTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlMathTranslator.cs index 756a868dfb..e74dd76271 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlMathTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlMathTranslator.cs @@ -24,86 +24,83 @@ public class NpgsqlMathTranslator : IMethodCallTranslator { static readonly Dictionary SupportedMethodTranslations = new() { - { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(decimal) }), "abs" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(double) }), "abs" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(float) }), "abs" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(int) }), "abs" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(long) }), "abs" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(short) }), "abs" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Ceiling), new[] { typeof(decimal) }), "ceiling" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Ceiling), new[] { typeof(double) }), "ceiling" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Floor), new[] { typeof(decimal) }), "floor" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Floor), new[] { typeof(double) }), "floor" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Pow), new[] { typeof(double), typeof(double) }), "power" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Exp), new[] { typeof(double) }), "exp" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Log10), new[] { typeof(double) }), "log" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Log), new[] { typeof(double) }), "ln" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(decimal) })!, "abs" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(double) })!, "abs" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(float) })!, "abs" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(int) })!, "abs" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(long) })!, "abs" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Abs), new[] { typeof(short) })!, "abs" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Ceiling), new[] { typeof(decimal) })!, "ceiling" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Ceiling), new[] { typeof(double) })!, "ceiling" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Floor), new[] { typeof(decimal) })!, "floor" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Floor), new[] { typeof(double) })!, "floor" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Pow), new[] { typeof(double), typeof(double) })!, "power" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Exp), new[] { typeof(double) })!, "exp" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Log10), new[] { typeof(double) })!, "log" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Log), new[] { typeof(double) })!, "ln" }, // Note: PostgreSQL has log(x,y) but only for decimal, whereas .NET has it only for double - { typeof(Math).GetRuntimeMethod(nameof(Math.Sqrt), new[] { typeof(double) }), "sqrt" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Acos), new[] { typeof(double) }), "acos" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Asin), new[] { typeof(double) }), "asin" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Atan), new[] { typeof(double) }), "atan" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Atan2), new[] { typeof(double), typeof(double) }), "atan2" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Cos), new[] { typeof(double) }), "cos" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Sin), new[] { typeof(double) }), "sin" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Tan), new[] { typeof(double) }), "tan" }, - - { typeof(Math).GetRuntimeMethod(nameof(Math.Round), new[] { typeof(double) }), "round" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Round), new[] { typeof(decimal) }), "round" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Truncate), new[] { typeof(double) }), "trunc" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Truncate), new[] { typeof(decimal) }), "trunc" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Sqrt), new[] { typeof(double) })!, "sqrt" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Acos), new[] { typeof(double) })!, "acos" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Asin), new[] { typeof(double) })!, "asin" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Atan), new[] { typeof(double) })!, "atan" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Atan2), new[] { typeof(double), typeof(double) })!, "atan2" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Cos), new[] { typeof(double) })!, "cos" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Sin), new[] { typeof(double) })!, "sin" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Tan), new[] { typeof(double) })!, "tan" }, + + { typeof(Math).GetRuntimeMethod(nameof(Math.Round), new[] { typeof(double) })!, "round" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Round), new[] { typeof(decimal) })!, "round" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Truncate), new[] { typeof(double) })!, "trunc" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Truncate), new[] { typeof(decimal) })!, "trunc" }, // https://www.postgresql.org/docs/current/functions-conditional.html#FUNCTIONS-GREATEST-LEAST - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(decimal), typeof(decimal) }), "greatest" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(double), typeof(double) }), "greatest" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(float), typeof(float) }), "greatest" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(int), typeof(int) }), "greatest" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(long), typeof(long) }), "greatest" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(short), typeof(short) }), "greatest" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(decimal), typeof(decimal) })!, "greatest" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(double), typeof(double) })!, "greatest" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(float), typeof(float) })!, "greatest" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(int), typeof(int) })!, "greatest" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(long), typeof(long) })!, "greatest" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Max), new[] { typeof(short), typeof(short) })!, "greatest" }, // https://www.postgresql.org/docs/current/functions-conditional.html#FUNCTIONS-GREATEST-LEAST - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(decimal), typeof(decimal) }), "least" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(double), typeof(double) }), "least" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(float), typeof(float) }), "least" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(int), typeof(int) }), "least" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(long), typeof(long) }), "least" }, - { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(short), typeof(short) }), "least" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(decimal), typeof(decimal) })!, "least" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(double), typeof(double) })!, "least" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(float), typeof(float) })!, "least" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(int), typeof(int) })!, "least" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(long), typeof(long) })!, "least" }, + { typeof(Math).GetRuntimeMethod(nameof(Math.Min), new[] { typeof(short), typeof(short) })!, "least" }, }; - static readonly IEnumerable SignMethodInfos = new[] + private static readonly IEnumerable SignMethodInfos = new[] { - typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(decimal) }), - typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(double) }), - typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(float) }), - typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(int) }), - typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(long) }), - typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(sbyte) }), - typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(short) }) + typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(decimal) })!, + typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(double) })!, + typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(float) })!, + typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(int) })!, + typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(long) })!, + typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(sbyte) })!, + typeof(Math).GetRuntimeMethod(nameof(Math.Sign), new[] { typeof(short) })! }; - static readonly MethodInfo RoundDecimalTwoParams = typeof(Math).GetRuntimeMethod(nameof(Math.Round), new[] { typeof(decimal), typeof(int) }); - - static readonly MethodInfo DoubleIsNanMethodInfo - = typeof(double).GetRuntimeMethod(nameof(double.IsNaN), new[] { typeof(double) }); - static readonly MethodInfo DoubleIsPositiveInfinityMethodInfo - = typeof(double).GetRuntimeMethod(nameof(double.IsPositiveInfinity), new[] { typeof(double) }); - static readonly MethodInfo DoubleIsNegativeInfinityMethodInfo - = typeof(double).GetRuntimeMethod(nameof(double.IsNegativeInfinity), new[] { typeof(double) }); - - static readonly MethodInfo FloatIsNanMethodInfo - = typeof(float).GetRuntimeMethod(nameof(float.IsNaN), new[] { typeof(float) }); - static readonly MethodInfo FloatIsPositiveInfinityMethodInfo - = typeof(float).GetRuntimeMethod(nameof(float.IsPositiveInfinity), new[] { typeof(float) }); - static readonly MethodInfo FloatIsNegativeInfinityMethodInfo - = typeof(float).GetRuntimeMethod(nameof(float.IsNegativeInfinity), new[] { typeof(float) }); - - readonly IRelationalTypeMappingSource _typeMappingSource; - readonly ISqlExpressionFactory _sqlExpressionFactory; - - /// - /// Initializes a new instance of the class. - /// - /// The SQL expression factory to use when generating expressions.. + private static readonly MethodInfo RoundDecimalTwoParams + = typeof(Math).GetRuntimeMethod(nameof(Math.Round), new[] { typeof(decimal), typeof(int) })!; + + private static readonly MethodInfo DoubleIsNanMethodInfo + = typeof(double).GetRuntimeMethod(nameof(double.IsNaN), new[] { typeof(double) })!; + private static readonly MethodInfo DoubleIsPositiveInfinityMethodInfo + = typeof(double).GetRuntimeMethod(nameof(double.IsPositiveInfinity), new[] { typeof(double) })!; + private static readonly MethodInfo DoubleIsNegativeInfinityMethodInfo + = typeof(double).GetRuntimeMethod(nameof(double.IsNegativeInfinity), new[] { typeof(double) })!; + + private static readonly MethodInfo FloatIsNanMethodInfo + = typeof(float).GetRuntimeMethod(nameof(float.IsNaN), new[] { typeof(float) })!; + private static readonly MethodInfo FloatIsPositiveInfinityMethodInfo + = typeof(float).GetRuntimeMethod(nameof(float.IsPositiveInfinity), new[] { typeof(float) })!; + private static readonly MethodInfo FloatIsNegativeInfinityMethodInfo + = typeof(float).GetRuntimeMethod(nameof(float.IsNegativeInfinity), new[] { typeof(float) })!; + + private readonly IRelationalTypeMappingSource _typeMappingSource; + private readonly ISqlExpressionFactory _sqlExpressionFactory; + public NpgsqlMathTranslator( [NotNull] IRelationalTypeMappingSource typeMappingSource, [NotNull] ISqlExpressionFactory sqlExpressionFactory) @@ -113,8 +110,8 @@ public NpgsqlMathTranslator( } /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkTranslator.cs index 77f97a1830..975f72de73 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkTranslator.cs @@ -23,19 +23,19 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte /// public class NpgsqlNetworkTranslator : IMethodCallTranslator { - static readonly MethodInfo IPAddressParse = - typeof(IPAddress).GetRuntimeMethod(nameof(IPAddress.Parse), new[] { typeof(string) }); + private static readonly MethodInfo IPAddressParse = + typeof(IPAddress).GetRuntimeMethod(nameof(IPAddress.Parse), new[] { typeof(string) })!; - static readonly MethodInfo PhysicalAddressParse = - typeof(PhysicalAddress).GetRuntimeMethod(nameof(PhysicalAddress.Parse), new[] { typeof(string) }); + private static readonly MethodInfo PhysicalAddressParse = + typeof(PhysicalAddress).GetRuntimeMethod(nameof(PhysicalAddress.Parse), new[] { typeof(string) })!; - readonly IRelationalTypeMappingSource _typeMappingSource; - readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly IRelationalTypeMappingSource _typeMappingSource; + private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; - readonly RelationalTypeMapping _boolMapping; - readonly RelationalTypeMapping _inetMapping; - readonly RelationalTypeMapping _cidrMapping; - readonly RelationalTypeMapping _macaddr8Mapping; + private readonly RelationalTypeMapping _boolMapping; + private readonly RelationalTypeMapping _inetMapping; + private readonly RelationalTypeMapping _cidrMapping; + private readonly RelationalTypeMapping _macaddr8Mapping; public NpgsqlNetworkTranslator( [NotNull] IRelationalTypeMappingSource typeMappingSource, @@ -43,15 +43,15 @@ public NpgsqlNetworkTranslator( { _typeMappingSource = typeMappingSource; _sqlExpressionFactory = sqlExpressionFactory; - _boolMapping = typeMappingSource.FindMapping(typeof(bool)); - _inetMapping = typeMappingSource.FindMapping("inet"); - _cidrMapping = typeMappingSource.FindMapping("cidr"); - _macaddr8Mapping = typeMappingSource.FindMapping("macaddr8"); + _boolMapping = typeMappingSource.FindMapping(typeof(bool))!; + _inetMapping = typeMappingSource.FindMapping("inet")!; + _cidrMapping = typeMappingSource.FindMapping("cidr")!; + _macaddr8Mapping = typeMappingSource.FindMapping("macaddr8")!; } /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) @@ -137,14 +137,14 @@ public virtual SqlExpression Translate( nameof(NpgsqlNetworkDbFunctionsExtensions.Truncate) => NullPropagatingFunction("trunc", new[] { arguments[1] }, typeof(PhysicalAddress), arguments[1].TypeMapping), nameof(NpgsqlNetworkDbFunctionsExtensions.Set7BitMac8) => NullPropagatingFunction("macaddr8_set7bit", new[] { arguments[1] }, typeof(PhysicalAddress), _macaddr8Mapping), - _ => (SqlExpression)null + _ => null }; SqlFunctionExpression NullPropagatingFunction( string name, SqlExpression[] arguments, Type returnType, - RelationalTypeMapping typeMapping = null) + RelationalTypeMapping? typeMapping = null) => _sqlExpressionFactory.Function( name, arguments, diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNewGuidTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNewGuidTranslator.cs index 2071d62f0a..66fefe20cb 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNewGuidTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNewGuidTranslator.cs @@ -18,10 +18,10 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte /// public class NpgsqlNewGuidTranslator : IMethodCallTranslator { - static readonly MethodInfo MethodInfo = typeof(Guid).GetRuntimeMethod(nameof(Guid.NewGuid), Array.Empty()); + private static readonly MethodInfo MethodInfo = typeof(Guid).GetRuntimeMethod(nameof(Guid.NewGuid), Array.Empty())!; - readonly ISqlExpressionFactory _sqlExpressionFactory; - readonly string _uuidGenerationFunction; + private readonly ISqlExpressionFactory _sqlExpressionFactory; + private readonly string _uuidGenerationFunction; public NpgsqlNewGuidTranslator( [NotNull] ISqlExpressionFactory sqlExpressionFactory, @@ -31,8 +31,8 @@ public NpgsqlNewGuidTranslator( _uuidGenerationFunction = postgresVersion.AtLeast(13) ? "gen_random_uuid" : "uuid_generate_v4"; } - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlObjectToStringTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlObjectToStringTranslator.cs index 9ec856ea1e..8650d77dfe 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlObjectToStringTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlObjectToStringTranslator.cs @@ -12,7 +12,7 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte { public class NpgsqlObjectToStringTranslator : IMethodCallTranslator { - static readonly List SupportedTypes = new() + private static readonly List SupportedTypes = new() { typeof(int), typeof(long), @@ -34,13 +34,13 @@ public class NpgsqlObjectToStringTranslator : IMethodCallTranslator typeof(sbyte), }; - readonly ISqlExpressionFactory _sqlExpressionFactory; + private readonly ISqlExpressionFactory _sqlExpressionFactory; public NpgsqlObjectToStringTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory) => _sqlExpressionFactory = sqlExpressionFactory; - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRandomTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRandomTranslator.cs index e470e4c7aa..95ccc68c93 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRandomTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRandomTranslator.cs @@ -13,15 +13,15 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte public class NpgsqlRandomTranslator : IMethodCallTranslator { private static readonly MethodInfo _methodInfo - = typeof(DbFunctionsExtensions).GetRuntimeMethod(nameof(DbFunctionsExtensions.Random), new[] { typeof(DbFunctions) }); + = typeof(DbFunctionsExtensions).GetRuntimeMethod(nameof(DbFunctionsExtensions.Random), new[] { typeof(DbFunctions) })!; private readonly ISqlExpressionFactory _sqlExpressionFactory; public NpgsqlRandomTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory) => _sqlExpressionFactory = sqlExpressionFactory; - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRangeTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRangeTranslator.cs index 954650e46b..3899bacc77 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRangeTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRangeTranslator.cs @@ -23,9 +23,9 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte /// public class NpgsqlRangeTranslator : IMethodCallTranslator, IMemberTranslator { - readonly IRelationalTypeMappingSource _typeMappingSource; - readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; - readonly RelationalTypeMapping _boolMapping; + private readonly IRelationalTypeMappingSource _typeMappingSource; + private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly RelationalTypeMapping _boolMapping; public NpgsqlRangeTranslator( [NotNull] IRelationalTypeMappingSource typeMappingSource, @@ -33,12 +33,12 @@ public NpgsqlRangeTranslator( { _typeMappingSource = typeMappingSource; _sqlExpressionFactory = npgsqlSqlExpressionFactory; - _boolMapping = typeMappingSource.FindMapping(typeof(bool)); + _boolMapping = typeMappingSource.FindMapping(typeof(bool))!; } /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) @@ -91,7 +91,7 @@ public virtual SqlExpression Translate( } /// - public virtual SqlExpression Translate(SqlExpression instance, + public virtual SqlExpression? Translate(SqlExpression? instance, MemberInfo member, Type returnType, IDiagnosticsLogger logger) @@ -102,7 +102,7 @@ public virtual SqlExpression Translate(SqlExpression instance, if (member.Name == nameof(NpgsqlRange.LowerBound) || member.Name == nameof(NpgsqlRange.UpperBound)) { - var typeMapping = instance.TypeMapping is NpgsqlRangeTypeMapping rangeMapping + var typeMapping = instance!.TypeMapping is NpgsqlRangeTypeMapping rangeMapping ? rangeMapping.SubtypeMapping : _typeMappingSource.FindMapping(returnType); @@ -125,11 +125,11 @@ public virtual SqlExpression Translate(SqlExpression instance, return member.Name switch { - nameof(NpgsqlRange.IsEmpty) => SingleArgBoolFunction("isempty", instance), - nameof(NpgsqlRange.LowerBoundIsInclusive) => SingleArgBoolFunction("lower_inc", instance), - nameof(NpgsqlRange.UpperBoundIsInclusive) => SingleArgBoolFunction("upper_inc", instance), - nameof(NpgsqlRange.LowerBoundInfinite) => SingleArgBoolFunction("lower_inf", instance), - nameof(NpgsqlRange.UpperBoundInfinite) => SingleArgBoolFunction("upper_inf", instance), + nameof(NpgsqlRange.IsEmpty) => SingleArgBoolFunction("isempty", instance!), + nameof(NpgsqlRange.LowerBoundIsInclusive) => SingleArgBoolFunction("lower_inc", instance!), + nameof(NpgsqlRange.UpperBoundIsInclusive) => SingleArgBoolFunction("upper_inc", instance!), + nameof(NpgsqlRange.LowerBoundInfinite) => SingleArgBoolFunction("lower_inf", instance!), + nameof(NpgsqlRange.UpperBoundInfinite) => SingleArgBoolFunction("upper_inf", instance!), _ => null }; @@ -145,7 +145,7 @@ SqlFunctionExpression SingleArgBoolFunction(string name, SqlExpression argument) static readonly ConcurrentDictionary _defaults = new(); - static object GetDefaultValue(Type type) - => type.IsValueType ? _defaults.GetOrAdd(type, Activator.CreateInstance) : null; + static object? GetDefaultValue(Type type) + => type.IsValueType ? _defaults.GetOrAdd(type, Activator.CreateInstance!) : null; } } diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRegexIsMatchTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRegexIsMatchTranslator.cs index d127b5ce95..9ff25ac5ad 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRegexIsMatchTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlRegexIsMatchTranslator.cs @@ -17,11 +17,11 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte /// public class NpgsqlRegexIsMatchTranslator : IMethodCallTranslator { - static readonly MethodInfo IsMatch = - typeof(Regex).GetRuntimeMethod(nameof(Regex.IsMatch), new[] { typeof(string), typeof(string) }); + private static readonly MethodInfo IsMatch = + typeof(Regex).GetRuntimeMethod(nameof(Regex.IsMatch), new[] { typeof(string), typeof(string) })!; - static readonly MethodInfo IsMatchWithRegexOptions = - typeof(Regex).GetRuntimeMethod(nameof(Regex.IsMatch), new[] { typeof(string), typeof(string), typeof(RegexOptions) }); + private static readonly MethodInfo IsMatchWithRegexOptions = + typeof(Regex).GetRuntimeMethod(nameof(Regex.IsMatch), new[] { typeof(string), typeof(string), typeof(RegexOptions) })!; const RegexOptions UnsupportedRegexOptions = RegexOptions.RightToLeft | RegexOptions.ECMAScript; @@ -31,8 +31,8 @@ public NpgsqlRegexIsMatchTranslator([NotNull] NpgsqlSqlExpressionFactory sqlExpr => _sqlExpressionFactory = sqlExpressionFactory; /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) @@ -47,8 +47,8 @@ public virtual SqlExpression Translate( if (method == IsMatch) options = RegexOptions.None; - else if (arguments[2] is SqlConstantExpression constantOptionsExpr) - options = (RegexOptions)constantOptionsExpr.Value; + else if (arguments[2] is SqlConstantExpression { Value: RegexOptions regexOptions }) + options = regexOptions; else return null; // We don't support non-constant regex options diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMemberTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMemberTranslator.cs index dea2c9e086..e6bd20421c 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMemberTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMemberTranslator.cs @@ -14,12 +14,12 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte /// public class NpgsqlStringMemberTranslator : IMemberTranslator { - readonly ISqlExpressionFactory _sqlExpressionFactory; + private readonly ISqlExpressionFactory _sqlExpressionFactory; public NpgsqlStringMemberTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory) => _sqlExpressionFactory = sqlExpressionFactory; - public virtual SqlExpression Translate(SqlExpression instance, + public virtual SqlExpression? Translate(SqlExpression? instance, MemberInfo member, Type returnType, IDiagnosticsLogger logger) diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMethodTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMethodTranslator.cs index bdf4b95310..c392b9fbb9 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMethodTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlStringMethodTranslator.cs @@ -23,46 +23,46 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte public class NpgsqlStringMethodTranslator : IMethodCallTranslator { // Note: This is the PostgreSQL default and does not need to be explicitly specified - const char LikeEscapeChar = '\\'; + private const char LikeEscapeChar = '\\'; - readonly ISqlExpressionFactory _sqlExpressionFactory; - readonly SqlConstantExpression _whitespace; - readonly RelationalTypeMapping _textTypeMapping; + private readonly ISqlExpressionFactory _sqlExpressionFactory; + private readonly SqlConstantExpression _whitespace; + private readonly RelationalTypeMapping _textTypeMapping; #region MethodInfo - static readonly MethodInfo Contains = typeof(string).GetRuntimeMethod(nameof(string.Contains), new[] { typeof(string) }); - static readonly MethodInfo DbFunctionsReverse = typeof(NpgsqlDbFunctionsExtensions).GetRuntimeMethod(nameof(NpgsqlDbFunctionsExtensions.Reverse), new[] { typeof(DbFunctions), typeof(string) }); - static readonly MethodInfo EndsWith = typeof(string).GetRuntimeMethod(nameof(string.EndsWith), new[] { typeof(string) }); - static readonly MethodInfo IndexOfChar = typeof(string).GetRuntimeMethod(nameof(string.IndexOf), new[] { typeof(char) }); - static readonly MethodInfo IndexOfString = typeof(string).GetRuntimeMethod(nameof(string.IndexOf), new[] { typeof(string) }); - static readonly MethodInfo IsNullOrWhiteSpace = typeof(string).GetRuntimeMethod(nameof(string.IsNullOrWhiteSpace), new[] { typeof(string) }); - static readonly MethodInfo PadLeft = typeof(string).GetRuntimeMethod(nameof(string.PadLeft), new[] { typeof(int) }); - static readonly MethodInfo PadLeftWithChar = typeof(string).GetRuntimeMethod(nameof(string.PadLeft), new[] { typeof(int), typeof(char) }); - static readonly MethodInfo PadRight = typeof(string).GetRuntimeMethod(nameof(string.PadRight), new[] { typeof(int) }); - static readonly MethodInfo PadRightWithChar = typeof(string).GetRuntimeMethod(nameof(string.PadRight), new[] { typeof(int), typeof(char) }); - static readonly MethodInfo Replace = typeof(string).GetRuntimeMethod(nameof(string.Replace), new[] { typeof(string), typeof(string) }); - static readonly MethodInfo StartsWith = typeof(string).GetRuntimeMethod(nameof(string.StartsWith), new[] { typeof(string) }); - static readonly MethodInfo Substring = typeof(string).GetTypeInfo().GetDeclaredMethods(nameof(string.Substring)).Single(m => m.GetParameters().Length == 1); - static readonly MethodInfo SubstringWithLength = typeof(string).GetTypeInfo().GetDeclaredMethods(nameof(string.Substring)).Single(m => m.GetParameters().Length == 2); - static readonly MethodInfo ToLower = typeof(string).GetRuntimeMethod(nameof(string.ToLower), Array.Empty()); - static readonly MethodInfo ToUpper = typeof(string).GetRuntimeMethod(nameof(string.ToUpper), Array.Empty()); - static readonly MethodInfo TrimBothWithNoParam = typeof(string).GetRuntimeMethod(nameof(string.Trim), Type.EmptyTypes); - static readonly MethodInfo TrimBothWithChars = typeof(string).GetRuntimeMethod(nameof(string.Trim), new[] { typeof(char[]) }); - static readonly MethodInfo TrimBothWithSingleChar = typeof(string).GetRuntimeMethod(nameof(string.Trim), new[] { typeof(char) }); - static readonly MethodInfo TrimEndWithNoParam = typeof(string).GetRuntimeMethod(nameof(string.TrimEnd), new Type[0]); - static readonly MethodInfo TrimEndWithChars = typeof(string).GetRuntimeMethod(nameof(string.TrimEnd), new[] { typeof(char[]) }); - static readonly MethodInfo TrimEndWithSingleChar = typeof(string).GetRuntimeMethod(nameof(string.TrimEnd), new[] { typeof(char) }); - static readonly MethodInfo TrimStartWithNoParam = typeof(string).GetRuntimeMethod(nameof(string.TrimStart), new Type[0]); - static readonly MethodInfo TrimStartWithChars = typeof(string).GetRuntimeMethod(nameof(string.TrimStart), new[] { typeof(char[]) }); - static readonly MethodInfo TrimStartWithSingleChar = typeof(string).GetRuntimeMethod(nameof(string.TrimStart), new[] { typeof(char) }); - - static readonly MethodInfo FirstOrDefaultMethodInfoWithoutArgs + private static readonly MethodInfo Contains = typeof(string).GetRuntimeMethod(nameof(string.Contains), new[] { typeof(string) })!; + private static readonly MethodInfo DbFunctionsReverse = typeof(NpgsqlDbFunctionsExtensions).GetRuntimeMethod(nameof(NpgsqlDbFunctionsExtensions.Reverse), new[] { typeof(DbFunctions), typeof(string) })!; + private static readonly MethodInfo EndsWith = typeof(string).GetRuntimeMethod(nameof(string.EndsWith), new[] { typeof(string) })!; + private static readonly MethodInfo IndexOfChar = typeof(string).GetRuntimeMethod(nameof(string.IndexOf), new[] { typeof(char) })!; + private static readonly MethodInfo IndexOfString = typeof(string).GetRuntimeMethod(nameof(string.IndexOf), new[] { typeof(string) })!; + private static readonly MethodInfo IsNullOrWhiteSpace = typeof(string).GetRuntimeMethod(nameof(string.IsNullOrWhiteSpace), new[] { typeof(string) })!; + private static readonly MethodInfo PadLeft = typeof(string).GetRuntimeMethod(nameof(string.PadLeft), new[] { typeof(int) })!; + private static readonly MethodInfo PadLeftWithChar = typeof(string).GetRuntimeMethod(nameof(string.PadLeft), new[] { typeof(int), typeof(char) })!; + private static readonly MethodInfo PadRight = typeof(string).GetRuntimeMethod(nameof(string.PadRight), new[] { typeof(int) })!; + private static readonly MethodInfo PadRightWithChar = typeof(string).GetRuntimeMethod(nameof(string.PadRight), new[] { typeof(int), typeof(char) })!; + private static readonly MethodInfo Replace = typeof(string).GetRuntimeMethod(nameof(string.Replace), new[] { typeof(string), typeof(string) })!; + private static readonly MethodInfo StartsWith = typeof(string).GetRuntimeMethod(nameof(string.StartsWith), new[] { typeof(string) })!; + private static readonly MethodInfo Substring = typeof(string).GetTypeInfo().GetDeclaredMethods(nameof(string.Substring)).Single(m => m.GetParameters().Length == 1); + private static readonly MethodInfo SubstringWithLength = typeof(string).GetTypeInfo().GetDeclaredMethods(nameof(string.Substring)).Single(m => m.GetParameters().Length == 2); + private static readonly MethodInfo ToLower = typeof(string).GetRuntimeMethod(nameof(string.ToLower), Array.Empty())!; + private static readonly MethodInfo ToUpper = typeof(string).GetRuntimeMethod(nameof(string.ToUpper), Array.Empty())!; + private static readonly MethodInfo TrimBothWithNoParam = typeof(string).GetRuntimeMethod(nameof(string.Trim), Type.EmptyTypes)!; + private static readonly MethodInfo TrimBothWithChars = typeof(string).GetRuntimeMethod(nameof(string.Trim), new[] { typeof(char[]) })!; + private static readonly MethodInfo TrimBothWithSingleChar = typeof(string).GetRuntimeMethod(nameof(string.Trim), new[] { typeof(char) })!; + private static readonly MethodInfo TrimEndWithNoParam = typeof(string).GetRuntimeMethod(nameof(string.TrimEnd), new Type[0])!; + private static readonly MethodInfo TrimEndWithChars = typeof(string).GetRuntimeMethod(nameof(string.TrimEnd), new[] { typeof(char[]) })!; + private static readonly MethodInfo TrimEndWithSingleChar = typeof(string).GetRuntimeMethod(nameof(string.TrimEnd), new[] { typeof(char) })!; + private static readonly MethodInfo TrimStartWithNoParam = typeof(string).GetRuntimeMethod(nameof(string.TrimStart), new Type[0])!; + private static readonly MethodInfo TrimStartWithChars = typeof(string).GetRuntimeMethod(nameof(string.TrimStart), new[] { typeof(char[]) })!; + private static readonly MethodInfo TrimStartWithSingleChar = typeof(string).GetRuntimeMethod(nameof(string.TrimStart), new[] { typeof(char) })!; + + private static readonly MethodInfo FirstOrDefaultMethodInfoWithoutArgs = typeof(Enumerable).GetRuntimeMethods().Single( m => m.Name == nameof(Enumerable.FirstOrDefault) && m.GetParameters().Length == 1).MakeGenericMethod(typeof(char)); - static readonly MethodInfo LastOrDefaultMethodInfoWithoutArgs + private static readonly MethodInfo LastOrDefaultMethodInfoWithoutArgs = typeof(Enumerable).GetRuntimeMethods().Single( m => m.Name == nameof(Enumerable.LastOrDefault) && m.GetParameters().Length == 1).MakeGenericMethod(typeof(char)); @@ -77,11 +77,11 @@ public NpgsqlStringMethodTranslator( _whitespace = _sqlExpressionFactory.Constant( @" \t\n\r", // TODO: Complete this typeMappingSource.EStringTypeMapping); - _textTypeMapping = (RelationalTypeMapping)typeMappingSource.FindMapping(typeof(string)); + _textTypeMapping = (RelationalTypeMapping)typeMappingSource.FindMapping(typeof(string))!; } - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) @@ -89,14 +89,14 @@ public virtual SqlExpression Translate( if (method == IndexOfString || method == IndexOfChar) { var argument = arguments[0]; - var stringTypeMapping = ExpressionExtensions.InferTypeMapping(instance, argument); + var stringTypeMapping = ExpressionExtensions.InferTypeMapping(instance!, argument); return _sqlExpressionFactory.Subtract( _sqlExpressionFactory.Function( "strpos", new[] { - _sqlExpressionFactory.ApplyTypeMapping(instance, stringTypeMapping), + _sqlExpressionFactory.ApplyTypeMapping(instance!, stringTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(argument, stringTypeMapping) }, nullable: true, @@ -109,13 +109,13 @@ public virtual SqlExpression Translate( { var oldValue = arguments[0]; var newValue = arguments[1]; - var stringTypeMapping = ExpressionExtensions.InferTypeMapping(instance, oldValue, newValue); + var stringTypeMapping = ExpressionExtensions.InferTypeMapping(instance!, oldValue, newValue); return _sqlExpressionFactory.Function( "replace", new[] { - _sqlExpressionFactory.ApplyTypeMapping(instance, stringTypeMapping), + _sqlExpressionFactory.ApplyTypeMapping(instance!, stringTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(oldValue, stringTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(newValue, stringTypeMapping) }, @@ -129,26 +129,26 @@ public virtual SqlExpression Translate( { return _sqlExpressionFactory.Function( method == ToLower ? "lower" : "upper", - new[] { instance }, + new[] { instance! }, nullable: true, argumentsPropagateNullability: TrueArrays[1], method.ReturnType, - instance.TypeMapping); + instance!.TypeMapping); } if (method == Substring || method == SubstringWithLength) { var args = method == Substring - ? new[] { instance, GenerateOneBasedIndexExpression(arguments[0]) } - : new[] { instance, GenerateOneBasedIndexExpression(arguments[0]), arguments[1] }; + ? new[] { instance!, GenerateOneBasedIndexExpression(arguments[0]) } + : new[] { instance!, GenerateOneBasedIndexExpression(arguments[0]), arguments[1] }; return _sqlExpressionFactory.Function( "substring", args, nullable: true, argumentsPropagateNullability: TrueArrays[args.Length], method.ReturnType, - instance.TypeMapping); + instance!.TypeMapping); } if (method == IsNullOrWhiteSpace) @@ -177,7 +177,7 @@ public virtual SqlExpression Translate( var isTrimBoth = method == TrimBothWithNoParam || method == TrimBothWithChars || method == TrimBothWithSingleChar; if (isTrimStart || isTrimEnd || isTrimBoth) { - char[] trimChars = null; + char[]? trimChars = null; if (method == TrimStartWithChars || method == TrimStartWithSingleChar || method == TrimEndWithChars || method == TrimEndWithSingleChar || @@ -189,28 +189,28 @@ public virtual SqlExpression Translate( trimChars = constantTrimChars.Value is char c ? new[] { c } - : (char[])constantTrimChars.Value; + : (char[]?)constantTrimChars.Value; } return _sqlExpressionFactory.Function( isTrimStart ? "ltrim" : isTrimEnd ? "rtrim" : "btrim", new[] { - instance, + instance!, trimChars == null || trimChars.Length == 0 ? _whitespace : _sqlExpressionFactory.Constant(new string(trimChars)) }, nullable: true, argumentsPropagateNullability: TrueArrays[2], - instance.Type, + instance!.Type, instance.TypeMapping); } if (method == Contains) { var pattern = arguments[0]; - var stringTypeMapping = ExpressionExtensions.InferTypeMapping(instance, pattern); + var stringTypeMapping = ExpressionExtensions.InferTypeMapping(instance!, pattern); instance = _sqlExpressionFactory.ApplyTypeMapping(instance, stringTypeMapping); pattern = _sqlExpressionFactory.ApplyTypeMapping(pattern, stringTypeMapping); @@ -219,7 +219,7 @@ public virtual SqlExpression Translate( "strpos", new[] { - _sqlExpressionFactory.ApplyTypeMapping(instance, stringTypeMapping), + _sqlExpressionFactory.ApplyTypeMapping(instance!, stringTypeMapping), _sqlExpressionFactory.ApplyTypeMapping(pattern, stringTypeMapping) }, nullable: true, @@ -229,7 +229,7 @@ public virtual SqlExpression Translate( if (pattern is SqlConstantExpression constantPattern) { - return (string)constantPattern.Value == string.Empty + return (string?)constantPattern.Value == string.Empty ? (SqlExpression)_sqlExpressionFactory.Constant(true) : strposCheck; } @@ -245,15 +245,15 @@ public virtual SqlExpression Translate( { var args = method == PadLeft || method == PadRight - ? new[] { instance, arguments[0] } - : new[] { instance, arguments[0], arguments[1] }; + ? new[] { instance!, arguments[0] } + : new[] { instance!, arguments[0], arguments[1] }; return _sqlExpressionFactory.Function( method == PadLeft || method == PadLeftWithChar ? "lpad" : "rpad", args, nullable: true, argumentsPropagateNullability: TrueArrays[args.Length], - instance.Type, + instance!.Type, instance.TypeMapping); } @@ -302,9 +302,9 @@ public virtual SqlExpression Translate( } if (method == StartsWith) - return TranslateStartsEndsWith(instance, arguments[0], true); + return TranslateStartsEndsWith(instance!, arguments[0], true); if (method == EndsWith) - return TranslateStartsEndsWith(instance, arguments[0], false); + return TranslateStartsEndsWith(instance!, arguments[0], false); return null; } diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlTimeSpanMemberTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlTimeSpanMemberTranslator.cs index 7131cab9bc..21b02fcf4d 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlTimeSpanMemberTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlTimeSpanMemberTranslator.cs @@ -12,14 +12,14 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte { public class NpgsqlTimeSpanMemberTranslator : IMemberTranslator { - readonly ISqlExpressionFactory _sqlExpressionFactory; + private readonly ISqlExpressionFactory _sqlExpressionFactory; public NpgsqlTimeSpanMemberTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory) => _sqlExpressionFactory = sqlExpressionFactory; - static readonly bool[] FalseTrueArray = { false, true }; + private static readonly bool[] FalseTrueArray = { false, true }; - public virtual SqlExpression Translate(SqlExpression instance, + public virtual SqlExpression? Translate(SqlExpression? instance, MemberInfo member, Type returnType, IDiagnosticsLogger logger) @@ -27,7 +27,7 @@ public virtual SqlExpression Translate(SqlExpression instance, Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); - if (member.DeclaringType == typeof(TimeSpan)) + if (member.DeclaringType == typeof(TimeSpan) && instance is not null) { return member.Name switch { @@ -36,7 +36,7 @@ public virtual SqlExpression Translate(SqlExpression instance, nameof(TimeSpan.Minutes) => Floor(DatePart("minute", instance)), nameof(TimeSpan.Seconds) => Floor(DatePart("second", instance)), nameof(TimeSpan.Milliseconds) => _sqlExpressionFactory.Modulo( - Floor(DatePart("millisecond", instance)), + Floor(DatePart("millisecond", instance!)), _sqlExpressionFactory.Constant(1000)), _ => null }; diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlTrigramsMethodTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlTrigramsMethodTranslator.cs index b9c2b109ff..cbeafdece5 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlTrigramsMethodTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlTrigramsMethodTranslator.cs @@ -14,40 +14,40 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionTranslators.Inte { public class NpgsqlTrigramsMethodTranslator : IMethodCallTranslator { - static readonly Dictionary Functions = new() + private static readonly Dictionary Functions = new() { - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsShow), new[] { typeof(DbFunctions), typeof(string) })] = "show_trgm", - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsSimilarity), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "similarity", - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsWordSimilarity), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "word_similarity", - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsStrictWordSimilarity), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "strict_word_similarity" + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsShow), typeof(DbFunctions), typeof(string))] = "show_trgm", + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsSimilarity), typeof(DbFunctions), typeof(string), typeof(string))] = "similarity", + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsWordSimilarity), typeof(DbFunctions), typeof(string), typeof(string))] = "word_similarity", + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsStrictWordSimilarity), typeof(DbFunctions), typeof(string), typeof(string))] = "strict_word_similarity" }; - static readonly Dictionary BoolReturningOperators = new() + private static readonly Dictionary BoolReturningOperators = new() { - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsAreSimilar), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "%", - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsAreWordSimilar), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "<%", - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsAreNotWordSimilar), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "%>", - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsAreStrictWordSimilar), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "<<%", - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsAreNotStrictWordSimilar), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "%>>" + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsAreSimilar), typeof(DbFunctions), typeof(string), typeof(string))] = "%", + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsAreWordSimilar), typeof(DbFunctions), typeof(string), typeof(string))] = "<%", + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsAreNotWordSimilar), typeof(DbFunctions), typeof(string), typeof(string))] = "%>", + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsAreStrictWordSimilar), typeof(DbFunctions), typeof(string), typeof(string))] = "<<%", + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsAreNotStrictWordSimilar), typeof(DbFunctions), typeof(string), typeof(string))] = "%>>" }; - static readonly Dictionary FloatReturningOperators = new() + private static readonly Dictionary FloatReturningOperators = new() { - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsSimilarityDistance), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "<->", - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsWordSimilarityDistance), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "<<->", - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsWordSimilarityDistanceInverted), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "<->>", - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsStrictWordSimilarityDistance), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "<<<->", - [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsStrictWordSimilarityDistanceInverted), new[] { typeof(DbFunctions), typeof(string), typeof(string) })] = "<->>>" + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsSimilarityDistance), typeof(DbFunctions), typeof(string), typeof(string))] = "<->", + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsWordSimilarityDistance), typeof(DbFunctions), typeof(string), typeof(string))] = "<<->", + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsWordSimilarityDistanceInverted), typeof(DbFunctions), typeof(string), typeof(string))] = "<->>", + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsStrictWordSimilarityDistance), typeof(DbFunctions), typeof(string), typeof(string))] = "<<<->", + [GetRuntimeMethod(nameof(NpgsqlTrigramsDbFunctionsExtensions.TrigramsStrictWordSimilarityDistanceInverted), typeof(DbFunctions), typeof(string), typeof(string))] = "<->>>" }; - static MethodInfo GetRuntimeMethod(string name, params Type[] parameters) - => typeof(NpgsqlTrigramsDbFunctionsExtensions).GetRuntimeMethod(name, parameters); + private static MethodInfo GetRuntimeMethod(string name, params Type[] parameters) + => typeof(NpgsqlTrigramsDbFunctionsExtensions).GetRuntimeMethod(name, parameters)!; - readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; - readonly RelationalTypeMapping _boolMapping; - readonly RelationalTypeMapping _floatMapping; + private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly RelationalTypeMapping _boolMapping; + private readonly RelationalTypeMapping _floatMapping; - static readonly bool[][] TrueArrays = + private static readonly bool[][] TrueArrays = { Array.Empty(), new[] { true }, @@ -59,14 +59,14 @@ public NpgsqlTrigramsMethodTranslator( [NotNull] NpgsqlSqlExpressionFactory sqlExpressionFactory) { _sqlExpressionFactory = sqlExpressionFactory; - _boolMapping = typeMappingSource.FindMapping(typeof(bool)); - _floatMapping = typeMappingSource.FindMapping(typeof(float)); + _boolMapping = typeMappingSource.FindMapping(typeof(bool))!; + _floatMapping = typeMappingSource.FindMapping(typeof(float))!; } #pragma warning disable EF1001 /// - public virtual SqlExpression Translate( - SqlExpression instance, + public virtual SqlExpression? Translate( + SqlExpression? instance, MethodInfo method, IReadOnlyList arguments, IDiagnosticsLogger logger) diff --git a/src/EFCore.PG/Query/Expressions/Internal/PostgresAllExpression.cs b/src/EFCore.PG/Query/Expressions/Internal/PostgresAllExpression.cs index abcd655963..3aca5539ae 100644 --- a/src/EFCore.PG/Query/Expressions/Internal/PostgresAllExpression.cs +++ b/src/EFCore.PG/Query/Expressions/Internal/PostgresAllExpression.cs @@ -47,7 +47,7 @@ public PostgresAllExpression( [NotNull] SqlExpression item, [NotNull] SqlExpression array, PostgresAllOperatorType operatorType, - [CanBeNull] RelationalTypeMapping typeMapping) + [CanBeNull] RelationalTypeMapping? typeMapping) : base(typeof(bool), typeMapping) { if (!(array.Type.IsArrayOrGenericList() || array is SqlConstantExpression { Value: null })) @@ -68,10 +68,10 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) => Update((SqlExpression)visitor.Visit(Item), (SqlExpression)visitor.Visit(Array)); /// - public override bool Equals(object obj) => obj is PostgresAllExpression e && Equals(e); + public override bool Equals(object? obj) => obj is PostgresAllExpression e && Equals(e); /// - public virtual bool Equals(PostgresAllExpression other) + public virtual bool Equals(PostgresAllExpression? other) => ReferenceEquals(this, other) || other is object && base.Equals(other) && diff --git a/src/EFCore.PG/Query/Expressions/Internal/PostgresAnyExpression.cs b/src/EFCore.PG/Query/Expressions/Internal/PostgresAnyExpression.cs index b6acaf02d3..cfce6a910f 100644 --- a/src/EFCore.PG/Query/Expressions/Internal/PostgresAnyExpression.cs +++ b/src/EFCore.PG/Query/Expressions/Internal/PostgresAnyExpression.cs @@ -50,7 +50,7 @@ public PostgresAnyExpression( [NotNull] SqlExpression item, [NotNull] SqlExpression array, PostgresAnyOperatorType operatorType, - [CanBeNull] RelationalTypeMapping typeMapping) + [CanBeNull] RelationalTypeMapping? typeMapping) : base(typeof(bool), typeMapping) { if (!(array is SqlConstantExpression { Value: null })) @@ -76,10 +76,10 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) => Update((SqlExpression)visitor.Visit(Item), (SqlExpression)visitor.Visit(Array)); /// - public override bool Equals(object obj) => obj is PostgresAnyExpression e && Equals(e); + public override bool Equals(object? obj) => obj is PostgresAnyExpression e && Equals(e); /// - public virtual bool Equals(PostgresAnyExpression other) + public virtual bool Equals(PostgresAnyExpression? other) => ReferenceEquals(this, other) || other is object && base.Equals(other) && diff --git a/src/EFCore.PG/Query/Expressions/Internal/PostgresArrayIndexExpression.cs b/src/EFCore.PG/Query/Expressions/Internal/PostgresArrayIndexExpression.cs index 04cb3c1429..d5e2b02ab2 100644 --- a/src/EFCore.PG/Query/Expressions/Internal/PostgresArrayIndexExpression.cs +++ b/src/EFCore.PG/Query/Expressions/Internal/PostgresArrayIndexExpression.cs @@ -34,7 +34,7 @@ public PostgresArrayIndexExpression( [NotNull] SqlExpression array, [NotNull] SqlExpression index, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping) + [CanBeNull] RelationalTypeMapping? typeMapping) : base(type.UnwrapNullableType(), typeMapping) { Check.NotNull(array, nameof(array)); @@ -60,14 +60,14 @@ public virtual PostgresArrayIndexExpression Update([NotNull] SqlExpression array protected override Expression VisitChildren(ExpressionVisitor visitor) => Update((SqlExpression)visitor.Visit(Array), (SqlExpression)visitor.Visit(Index)); - public virtual bool Equals(PostgresArrayIndexExpression other) + public virtual bool Equals(PostgresArrayIndexExpression? other) => ReferenceEquals(this, other) || other is object && base.Equals(other) && Array.Equals(other.Array) && Index.Equals(other.Index); - public override bool Equals(object obj) => obj is PostgresArrayIndexExpression e && Equals(e); + public override bool Equals(object? obj) => obj is PostgresArrayIndexExpression e && Equals(e); public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), Array, Index); diff --git a/src/EFCore.PG/Query/Expressions/Internal/PostgresBinaryExpression.cs b/src/EFCore.PG/Query/Expressions/Internal/PostgresBinaryExpression.cs index 6f1c48e7c1..70d0095ecd 100644 --- a/src/EFCore.PG/Query/Expressions/Internal/PostgresBinaryExpression.cs +++ b/src/EFCore.PG/Query/Expressions/Internal/PostgresBinaryExpression.cs @@ -26,7 +26,7 @@ public PostgresBinaryExpression( [NotNull] SqlExpression left, [NotNull] SqlExpression right, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping) + [CanBeNull] RelationalTypeMapping? typeMapping) : base(type, typeMapping) { Check.NotNull(left, nameof(left)); @@ -150,7 +150,7 @@ protected override void Print(ExpressionPrinter expressionPrinter) } /// - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj != null && (ReferenceEquals(this, obj) || obj is PostgresBinaryExpression sqlBinaryExpression diff --git a/src/EFCore.PG/Query/Expressions/Internal/PostgresFunctionExpression.cs b/src/EFCore.PG/Query/Expressions/Internal/PostgresFunctionExpression.cs index 6631b9fede..f73416305a 100644 --- a/src/EFCore.PG/Query/Expressions/Internal/PostgresFunctionExpression.cs +++ b/src/EFCore.PG/Query/Expressions/Internal/PostgresFunctionExpression.cs @@ -19,6 +19,12 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal [DebuggerDisplay("{" + nameof(ToString) + "()}")] public class PostgresFunctionExpression : SqlFunctionExpression, IEquatable { + public new virtual IReadOnlyList Arguments + => base.Arguments!; + + public new virtual IReadOnlyList ArgumentsPropagateNullability + => base.ArgumentsPropagateNullability!; + /// /// List of argument names, corresponding position-wise to arguments in . /// Unnamed (positional) arguments must come first, so this list must contain possible nulls, followed by @@ -37,10 +43,10 @@ public static PostgresFunctionExpression CreateWithNamedArguments( [NotNull] IEnumerable arguments, [NotNull] IEnumerable argumentNames, bool nullable, - [CanBeNull] IEnumerable argumentsPropagateNullability, + [NotNull] IEnumerable argumentsPropagateNullability, bool builtIn, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping) + [CanBeNull] RelationalTypeMapping? typeMapping) { Check.NotNull(arguments, nameof(arguments)); Check.NotNull(argumentNames, nameof(argumentNames)); @@ -55,10 +61,10 @@ public static PostgresFunctionExpression CreateWithArgumentSeparators( [NotNull] IEnumerable arguments, [NotNull] IEnumerable argumentSeparators, bool nullable, - [CanBeNull] IEnumerable argumentsPropagateNullability, + [NotNull] IEnumerable argumentsPropagateNullability, bool builtIn, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping) + [CanBeNull] RelationalTypeMapping? typeMapping) { Check.NotNull(arguments, nameof(arguments)); Check.NotNull(argumentSeparators, nameof(argumentSeparators)); @@ -74,9 +80,9 @@ public static PostgresFunctionExpression CreateWithArgumentSeparators( [CanBeNull] IEnumerable? argumentNames, [CanBeNull] IEnumerable? argumentSeparators, bool nullable, - [CanBeNull] IEnumerable argumentsPropagateNullability, + [NotNull] IEnumerable argumentsPropagateNullability, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping) + [CanBeNull] RelationalTypeMapping? typeMapping) : base(name, arguments, nullable, argumentsPropagateNullability, type, typeMapping) { Check.NotEmpty(name, nameof(name)); @@ -94,14 +100,14 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) Check.NotNull(visitor, nameof(visitor)); var visited = base.VisitChildren(visitor); - return visited != this && visited is SqlFunctionExpression e + return visited != this && visited is PostgresFunctionExpression e ? new PostgresFunctionExpression( e.Name, e.Arguments, ArgumentNames, ArgumentSeparators, - IsNullable, ArgumentsPropagateNullability, Type, TypeMapping) + IsNullable, ArgumentsPropagateNullability!, Type, TypeMapping) : visited; } - public override SqlFunctionExpression ApplyTypeMapping(RelationalTypeMapping typeMapping) + public override SqlFunctionExpression ApplyTypeMapping(RelationalTypeMapping? typeMapping) => new PostgresFunctionExpression( Name, Arguments, @@ -112,11 +118,11 @@ public override SqlFunctionExpression ApplyTypeMapping(RelationalTypeMapping typ Type, typeMapping ?? TypeMapping); - public override SqlFunctionExpression Update(SqlExpression instance, IReadOnlyList arguments) + public override SqlFunctionExpression Update(SqlExpression? instance, IReadOnlyList? arguments) { Check.NotNull(arguments, nameof(arguments)); if (instance != null) - throw new ArgumentException($"Must be null", nameof(instance)); + throw new ArgumentException("Must be null", nameof(instance)); return !arguments.SequenceEqual(Arguments) ? new PostgresFunctionExpression( @@ -125,9 +131,9 @@ public override SqlFunctionExpression Update(SqlExpression instance, IReadOnlyLi : this; } - public override bool Equals(object obj) => obj is PostgresFunctionExpression pgFunction && Equals(pgFunction); + public override bool Equals(object? obj) => obj is PostgresFunctionExpression pgFunction && Equals(pgFunction); - public virtual bool Equals(PostgresFunctionExpression other) + public virtual bool Equals(PostgresFunctionExpression? other) => ReferenceEquals(this, other) || other is object && base.Equals(other) && diff --git a/src/EFCore.PG/Query/Expressions/Internal/PostgresILikeExpression.cs b/src/EFCore.PG/Query/Expressions/Internal/PostgresILikeExpression.cs index 8b30ee642b..bdefae0974 100644 --- a/src/EFCore.PG/Query/Expressions/Internal/PostgresILikeExpression.cs +++ b/src/EFCore.PG/Query/Expressions/Internal/PostgresILikeExpression.cs @@ -30,7 +30,7 @@ public class PostgresILikeExpression : SqlExpression, IEquatable. /// [CanBeNull] - public virtual SqlExpression EscapeChar { get; } + public virtual SqlExpression? EscapeChar { get; } /// /// Constructs a . @@ -42,8 +42,8 @@ public class PostgresILikeExpression : SqlExpression, IEquatable Update( (SqlExpression)visitor.Visit(Match), (SqlExpression)visitor.Visit(Pattern), - (SqlExpression)visitor.Visit(EscapeChar)); + EscapeChar is null ? null : (SqlExpression)visitor.Visit(EscapeChar)); public virtual PostgresILikeExpression Update( [NotNull] SqlExpression match, [NotNull] SqlExpression pattern, - [NotNull] SqlExpression escapeChar) + [CanBeNull] SqlExpression? escapeChar) => match == Match && pattern == Pattern && escapeChar == EscapeChar ? this : new PostgresILikeExpression(match, pattern, escapeChar, TypeMapping); /// - public override bool Equals(object obj) => obj is PostgresILikeExpression other && Equals(other); + public override bool Equals(object? obj) => obj is PostgresILikeExpression other && Equals(other); /// - public virtual bool Equals(PostgresILikeExpression other) + public virtual bool Equals(PostgresILikeExpression? other) => ReferenceEquals(this, other) || other is object && base.Equals(other) && diff --git a/src/EFCore.PG/Query/Expressions/Internal/PostgresJsonTraversalExpression.cs b/src/EFCore.PG/Query/Expressions/Internal/PostgresJsonTraversalExpression.cs index 3fc8a9894d..15d56416b5 100644 --- a/src/EFCore.PG/Query/Expressions/Internal/PostgresJsonTraversalExpression.cs +++ b/src/EFCore.PG/Query/Expressions/Internal/PostgresJsonTraversalExpression.cs @@ -39,7 +39,7 @@ public PostgresJsonTraversalExpression( [NotNull] IReadOnlyList path, bool returnsText, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping) + [CanBeNull] RelationalTypeMapping? typeMapping) : base(type, typeMapping) { if (returnsText && type != typeof(string)) @@ -75,10 +75,10 @@ public virtual PostgresJsonTraversalExpression Append([NotNull] SqlExpression pa } /// - public override bool Equals(object obj) => Equals(obj as PostgresJsonTraversalExpression); + public override bool Equals(object? obj) => Equals(obj as PostgresJsonTraversalExpression); /// - public virtual bool Equals(PostgresJsonTraversalExpression other) + public virtual bool Equals(PostgresJsonTraversalExpression? other) => ReferenceEquals(this, other) || other is object && base.Equals(other) && diff --git a/src/EFCore.PG/Query/Expressions/Internal/PostgresNewArrayExpression.cs b/src/EFCore.PG/Query/Expressions/Internal/PostgresNewArrayExpression.cs index 8a0da96416..736ec32e79 100644 --- a/src/EFCore.PG/Query/Expressions/Internal/PostgresNewArrayExpression.cs +++ b/src/EFCore.PG/Query/Expressions/Internal/PostgresNewArrayExpression.cs @@ -25,7 +25,7 @@ public class PostgresNewArrayExpression : SqlExpression public PostgresNewArrayExpression( [NotNull] IReadOnlyList expressions, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping) + [CanBeNull] RelationalTypeMapping? typeMapping) : base(type, typeMapping) { Check.NotNull(expressions, nameof(expressions)); @@ -46,7 +46,7 @@ protected override Expression VisitChildren(ExpressionVisitor visitor) { Check.NotNull(visitor, nameof(visitor)); - List newExpressions = null; + List? newExpressions = null; for (var i = 0; i < Expressions.Count; i++) { var expression = Expressions[i]; @@ -105,7 +105,7 @@ protected override void Print(ExpressionPrinter expressionPrinter) } /// - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj != null && (ReferenceEquals(this, obj) || obj is PostgresNewArrayExpression sqlBinaryExpression diff --git a/src/EFCore.PG/Query/Expressions/Internal/PostgresRegexMatchExpression.cs b/src/EFCore.PG/Query/Expressions/Internal/PostgresRegexMatchExpression.cs index 6dc46f398d..278d92800d 100644 --- a/src/EFCore.PG/Query/Expressions/Internal/PostgresRegexMatchExpression.cs +++ b/src/EFCore.PG/Query/Expressions/Internal/PostgresRegexMatchExpression.cs @@ -42,7 +42,7 @@ public PostgresRegexMatchExpression( [NotNull] SqlExpression match, [NotNull] SqlExpression pattern, RegexOptions options, - [CanBeNull] RelationalTypeMapping typeMapping) + [CanBeNull] RelationalTypeMapping? typeMapping) : base(typeof(bool), typeMapping) { Match = match; @@ -59,7 +59,7 @@ public virtual PostgresRegexMatchExpression Update([NotNull] SqlExpression match ? new PostgresRegexMatchExpression(match, pattern, Options, TypeMapping) : this; - public virtual bool Equals(PostgresRegexMatchExpression other) + public virtual bool Equals(PostgresRegexMatchExpression? other) => ReferenceEquals(this, other) || other is object && base.Equals(other) && @@ -67,7 +67,7 @@ other is object && Pattern.Equals(other.Pattern) && Options.Equals(other.Options); - public override bool Equals(object other) + public override bool Equals(object? other) => other is PostgresRegexMatchExpression otherRegexMatch && Equals(otherRegexMatch); public override int GetHashCode() diff --git a/src/EFCore.PG/Query/Expressions/Internal/PostgresUnknownBinaryExpression.cs b/src/EFCore.PG/Query/Expressions/Internal/PostgresUnknownBinaryExpression.cs index d09d8e2c4a..95b6be085d 100644 --- a/src/EFCore.PG/Query/Expressions/Internal/PostgresUnknownBinaryExpression.cs +++ b/src/EFCore.PG/Query/Expressions/Internal/PostgresUnknownBinaryExpression.cs @@ -42,13 +42,14 @@ public class PostgresUnknownBinaryExpression : SqlExpression, IEquatableThe right-hand expression. /// The operator symbol acting on the expression. /// The result type. + /// The type mapping for the expression. /// public PostgresUnknownBinaryExpression( [NotNull] SqlExpression left, [NotNull] SqlExpression right, [NotNull] string binaryOperator, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping = null) + [CanBeNull] RelationalTypeMapping? typeMapping = null) : base(type, typeMapping) { Left = Check.NotNull(left, nameof(left)); @@ -65,14 +66,14 @@ public virtual PostgresUnknownBinaryExpression Update([NotNull] SqlExpression le ? this : new PostgresUnknownBinaryExpression(left, right, Operator, Type, TypeMapping); - public virtual bool Equals(PostgresUnknownBinaryExpression other) + public virtual bool Equals(PostgresUnknownBinaryExpression? other) => ReferenceEquals(this, other) || other is object && Left.Equals(other.Left) && Right.Equals(other.Right) && Operator == other.Operator; - public override bool Equals(object obj) => obj is PostgresUnknownBinaryExpression e && Equals(e); + public override bool Equals(object? obj) => obj is PostgresUnknownBinaryExpression e && Equals(e); public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), Left, Right, Operator); diff --git a/src/EFCore.PG/Query/Internal/NpgsqlCompiledQueryCacheKeyGenerator.cs b/src/EFCore.PG/Query/Internal/NpgsqlCompiledQueryCacheKeyGenerator.cs index 8d82dae29a..8f1858c118 100644 --- a/src/EFCore.PG/Query/Internal/NpgsqlCompiledQueryCacheKeyGenerator.cs +++ b/src/EFCore.PG/Query/Internal/NpgsqlCompiledQueryCacheKeyGenerator.cs @@ -32,7 +32,7 @@ public NpgsqlCompiledQueryCacheKey( _reverseNullOrdering = reverseNullOrdering; } - public override bool Equals(object obj) + public override bool Equals(object? obj) => !(obj is null) && obj is NpgsqlCompiledQueryCacheKey key && Equals(key); diff --git a/src/EFCore.PG/Query/Internal/NpgsqlEvaluatableExpressionFilter.cs b/src/EFCore.PG/Query/Internal/NpgsqlEvaluatableExpressionFilter.cs index 07e7a98d7c..5b8779afe2 100644 --- a/src/EFCore.PG/Query/Internal/NpgsqlEvaluatableExpressionFilter.cs +++ b/src/EFCore.PG/Query/Internal/NpgsqlEvaluatableExpressionFilter.cs @@ -10,17 +10,18 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal { public class NpgsqlEvaluatableExpressionFilter : RelationalEvaluatableExpressionFilter { - [NotNull] static readonly MethodInfo TsQueryParse = - typeof(NpgsqlTsQuery).GetRuntimeMethod(nameof(NpgsqlTsQuery.Parse), new[] { typeof(string) }); + private static readonly MethodInfo TsQueryParse = + typeof(NpgsqlTsQuery).GetRuntimeMethod(nameof(NpgsqlTsQuery.Parse), new[] { typeof(string) })!; - [NotNull] static readonly MethodInfo TsVectorParse = - typeof(NpgsqlTsVector).GetRuntimeMethod(nameof(NpgsqlTsVector.Parse), new[] { typeof(string) }); + private static readonly MethodInfo TsVectorParse = + typeof(NpgsqlTsVector).GetRuntimeMethod(nameof(NpgsqlTsVector.Parse), new[] { typeof(string) })!; public NpgsqlEvaluatableExpressionFilter( [NotNull] EvaluatableExpressionFilterDependencies dependencies, [NotNull] RelationalEvaluatableExpressionFilterDependencies relationalDependencies) : base(dependencies, relationalDependencies) - {} + { + } public override bool IsEvaluatableExpression(Expression expression, IModel model) { diff --git a/src/EFCore.PG/Query/Internal/NpgsqlParameterBasedSqlProcessor.cs b/src/EFCore.PG/Query/Internal/NpgsqlParameterBasedSqlProcessor.cs index d3ef0ae585..2c618f0a3f 100644 --- a/src/EFCore.PG/Query/Internal/NpgsqlParameterBasedSqlProcessor.cs +++ b/src/EFCore.PG/Query/Internal/NpgsqlParameterBasedSqlProcessor.cs @@ -17,7 +17,7 @@ public NpgsqlParameterBasedSqlProcessor( /// protected override SelectExpression ProcessSqlNullability( - SelectExpression selectExpression, IReadOnlyDictionary parametersValues, out bool canCache) + SelectExpression selectExpression, IReadOnlyDictionary parametersValues, out bool canCache) { Check.NotNull(selectExpression, nameof(selectExpression)); Check.NotNull(parametersValues, nameof(parametersValues)); diff --git a/src/EFCore.PG/Query/Internal/NpgsqlParameterBasedSqlProcessorFactory.cs b/src/EFCore.PG/Query/Internal/NpgsqlParameterBasedSqlProcessorFactory.cs index 70a696fd02..ca0b890f34 100644 --- a/src/EFCore.PG/Query/Internal/NpgsqlParameterBasedSqlProcessorFactory.cs +++ b/src/EFCore.PG/Query/Internal/NpgsqlParameterBasedSqlProcessorFactory.cs @@ -5,7 +5,7 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal { public class NpgsqlParameterBasedSqlProcessorFactory : IRelationalParameterBasedSqlProcessorFactory { - readonly RelationalParameterBasedSqlProcessorDependencies _dependencies; + private readonly RelationalParameterBasedSqlProcessorDependencies _dependencies; public NpgsqlParameterBasedSqlProcessorFactory( [NotNull] RelationalParameterBasedSqlProcessorDependencies dependencies) diff --git a/src/EFCore.PG/Query/Internal/NpgsqlQueryCompilationContextFactory.cs b/src/EFCore.PG/Query/Internal/NpgsqlQueryCompilationContextFactory.cs index 4ab9aeb725..24466378bb 100644 --- a/src/EFCore.PG/Query/Internal/NpgsqlQueryCompilationContextFactory.cs +++ b/src/EFCore.PG/Query/Internal/NpgsqlQueryCompilationContextFactory.cs @@ -6,8 +6,8 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal { public class NpgsqlQueryCompilationContextFactory : IQueryCompilationContextFactory { - readonly QueryCompilationContextDependencies _dependencies; - readonly RelationalQueryCompilationContextDependencies _relationalDependencies; + private readonly QueryCompilationContextDependencies _dependencies; + private readonly RelationalQueryCompilationContextDependencies _relationalDependencies; public NpgsqlQueryCompilationContextFactory( [NotNull] QueryCompilationContextDependencies dependencies, diff --git a/src/EFCore.PG/Query/Internal/NpgsqlQuerySqlGenerator.cs b/src/EFCore.PG/Query/Internal/NpgsqlQuerySqlGenerator.cs index e483be7a19..43d1aca166 100644 --- a/src/EFCore.PG/Query/Internal/NpgsqlQuerySqlGenerator.cs +++ b/src/EFCore.PG/Query/Internal/NpgsqlQuerySqlGenerator.cs @@ -21,18 +21,18 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal /// public class NpgsqlQuerySqlGenerator : QuerySqlGenerator { - readonly ISqlGenerationHelper _sqlGenerationHelper; + private readonly ISqlGenerationHelper _sqlGenerationHelper; /// /// True if null ordering is reversed; otherwise false. /// - readonly bool _reverseNullOrderingEnabled; + private readonly bool _reverseNullOrderingEnabled; /// /// The backend version to target. If null, it means the user hasn't set a compatibility version, and the /// latest should be targeted. /// - readonly Version _postgresVersion; + private readonly Version _postgresVersion; /// public NpgsqlQuerySqlGenerator( @@ -204,6 +204,8 @@ protected override Expression VisitSqlBinary(SqlBinaryExpression binary) protected virtual Expression VisitPostgresNewArray([NotNull] PostgresNewArrayExpression postgresNewArrayExpression) { + Debug.Assert(postgresNewArrayExpression.TypeMapping is not null); + Sql.Append("ARRAY["); var first = true; foreach (var initializer in postgresNewArrayExpression.Expressions) @@ -328,6 +330,9 @@ protected virtual Expression VisitArrayIndex([NotNull] SqlBinaryExpression expre protected override Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpression) { + Debug.Assert(sqlUnaryExpression.TypeMapping is not null); + Debug.Assert(sqlUnaryExpression.Operand.TypeMapping is not null); + switch (sqlUnaryExpression.OperatorType) { case ExpressionType.Convert: @@ -673,10 +678,10 @@ public virtual Expression VisitPgFunction([NotNull] PostgresFunctionExpression e for (var i = 0; i < e.Arguments.Count; i++) { - if (i < e.ArgumentNames.Count && e.ArgumentNames[i] != null) + if (i < e.ArgumentNames.Count && e.ArgumentNames[i] is string argumentName) { Sql - .Append(e.ArgumentNames[i]) + .Append(argumentName) .Append(" => "); } @@ -693,7 +698,7 @@ public virtual Expression VisitPgFunction([NotNull] PostgresFunctionExpression e return e; } - static bool RequiresBrackets(SqlExpression expression) + private static bool RequiresBrackets(SqlExpression expression) => expression is SqlBinaryExpression || expression is LikeExpression || expression is PostgresBinaryExpression; } } diff --git a/src/EFCore.PG/Query/Internal/NpgsqlQuerySqlGeneratorFactory.cs b/src/EFCore.PG/Query/Internal/NpgsqlQuerySqlGeneratorFactory.cs index 06c1aa2c1a..8f10152845 100644 --- a/src/EFCore.PG/Query/Internal/NpgsqlQuerySqlGeneratorFactory.cs +++ b/src/EFCore.PG/Query/Internal/NpgsqlQuerySqlGeneratorFactory.cs @@ -9,8 +9,8 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal ///
public class NpgsqlQuerySqlGeneratorFactory : IQuerySqlGeneratorFactory { - [NotNull] readonly QuerySqlGeneratorDependencies _dependencies; - [NotNull] readonly INpgsqlOptions _npgsqlOptions; + private readonly QuerySqlGeneratorDependencies _dependencies; + private readonly INpgsqlOptions _npgsqlOptions; public NpgsqlQuerySqlGeneratorFactory( [NotNull] QuerySqlGeneratorDependencies dependencies, diff --git a/src/EFCore.PG/Query/Internal/NpgsqlSqlNullabilityProcessor.cs b/src/EFCore.PG/Query/Internal/NpgsqlSqlNullabilityProcessor.cs index c571f85984..77e18a4879 100644 --- a/src/EFCore.PG/Query/Internal/NpgsqlSqlNullabilityProcessor.cs +++ b/src/EFCore.PG/Query/Internal/NpgsqlSqlNullabilityProcessor.cs @@ -15,7 +15,7 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal /// public class NpgsqlSqlNullabilityProcessor : SqlNullabilityProcessor { - readonly ISqlExpressionFactory _sqlExpressionFactory; + private readonly ISqlExpressionFactory _sqlExpressionFactory; /// /// Creates a new instance of the class. @@ -172,7 +172,7 @@ protected virtual SqlExpression VisitArrayIndex( var array = Visit(arrayIndexExpression.Array, allowOptimizedExpansion, out var arrayNullable); var index = Visit(arrayIndexExpression.Index, allowOptimizedExpansion, out var indexNullable); - nullable = arrayNullable || indexNullable || ((NpgsqlArrayTypeMapping)arrayIndexExpression.Array.TypeMapping).IsElementNullable; + nullable = arrayNullable || indexNullable || ((NpgsqlArrayTypeMapping)arrayIndexExpression.Array.TypeMapping!).IsElementNullable; return arrayIndexExpression.Update(array, index); } @@ -250,7 +250,7 @@ protected virtual SqlExpression VisitNewArray( { Check.NotNull(newArrayExpression, nameof(newArrayExpression)); - List newInitializers = null; + List? newInitializers = null; for (var i = 0; i < newArrayExpression.Expressions.Count; i++) { var initializer = newArrayExpression.Expressions[i]; @@ -310,7 +310,7 @@ protected virtual SqlExpression VisitJsonTraversal( var expression = Visit(jsonTraversalExpression.Expression, out nullable); - List newPath = null; + List? newPath = null; for (var i = 0; i < jsonTraversalExpression.Path.Count; i++) { var pathComponent = jsonTraversalExpression.Path[i]; diff --git a/src/EFCore.PG/Query/Internal/NpgsqlSqlTranslatingExpressionVisitor.cs b/src/EFCore.PG/Query/Internal/NpgsqlSqlTranslatingExpressionVisitor.cs index f184a9a914..a2a1645be1 100644 --- a/src/EFCore.PG/Query/Internal/NpgsqlSqlTranslatingExpressionVisitor.cs +++ b/src/EFCore.PG/Query/Internal/NpgsqlSqlTranslatingExpressionVisitor.cs @@ -16,35 +16,36 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping; using Npgsql.EntityFrameworkCore.PostgreSQL.Utilities; using static Npgsql.EntityFrameworkCore.PostgreSQL.Utilities.Statics; +using CA = System.Diagnostics.CodeAnalysis; namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query.Internal { public class NpgsqlSqlTranslatingExpressionVisitor : RelationalSqlTranslatingExpressionVisitor { - static readonly ConstructorInfo DateTimeCtor1 = - typeof(DateTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) }); + private static readonly ConstructorInfo DateTimeCtor1 = + typeof(DateTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) })!; - static readonly ConstructorInfo DateTimeCtor2 = - typeof(DateTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) }); + private static readonly ConstructorInfo DateTimeCtor2 = + typeof(DateTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) })!; - static readonly MethodInfo Like2MethodInfo = - typeof(DbFunctionsExtensions) - .GetRuntimeMethod(nameof(DbFunctionsExtensions.Like), new[] { typeof(DbFunctions), typeof(string), typeof(string) }); + private static readonly MethodInfo Like2MethodInfo = + typeof(DbFunctionsExtensions).GetRuntimeMethod( + nameof(DbFunctionsExtensions.Like), new[] { typeof(DbFunctions), typeof(string), typeof(string) })!; // ReSharper disable once InconsistentNaming - static readonly MethodInfo ILike2MethodInfo - = typeof(NpgsqlDbFunctionsExtensions) - .GetRuntimeMethod(nameof(NpgsqlDbFunctionsExtensions.ILike), new[] { typeof(DbFunctions), typeof(string), typeof(string) }); + private static readonly MethodInfo ILike2MethodInfo + = typeof(NpgsqlDbFunctionsExtensions).GetRuntimeMethod( + nameof(NpgsqlDbFunctionsExtensions.ILike), new[] { typeof(DbFunctions), typeof(string), typeof(string) })!; - static readonly MethodInfo ObjectEquals - = typeof(object).GetRuntimeMethod(nameof(object.Equals), new[] { typeof(object), typeof(object) }); + private static readonly MethodInfo ObjectEquals + = typeof(object).GetRuntimeMethod(nameof(object.Equals), new[] { typeof(object), typeof(object) })!; - readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; - readonly IRelationalTypeMappingSource _typeMappingSource; - readonly NpgsqlJsonPocoTranslator _jsonPocoTranslator; - readonly NpgsqlLTreeTranslator _ltreeTranslator; + private readonly NpgsqlSqlExpressionFactory _sqlExpressionFactory; + private readonly IRelationalTypeMappingSource _typeMappingSource; + private readonly NpgsqlJsonPocoTranslator _jsonPocoTranslator; + private readonly NpgsqlLTreeTranslator _ltreeTranslator; - static Type _nodaTimePeriodType; + private static Type? _nodaTimePeriodType; public NpgsqlSqlTranslatingExpressionVisitor( [NotNull] RelationalSqlTranslatingExpressionVisitorDependencies dependencies, @@ -125,7 +126,7 @@ protected override Expression VisitUnary(UnaryExpression unaryExpression) // Translate Length on byte[], but only if the type mapping is for bytea. There's also array of bytes // (mapped to smallint[]), which is handled below with CARDINALITY. - if (sqlOperand.Type == typeof(byte[]) && + if (sqlOperand!.Type == typeof(byte[]) && (sqlOperand.TypeMapping == null || sqlOperand.TypeMapping is NpgsqlByteArrayTypeMapping)) { return _sqlExpressionFactory.Function( @@ -164,7 +165,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCall) /// Identifies complex array-related constructs which cannot be translated in regular method translators, since /// they require accessing lambdas. /// - private Expression VisitArrayMethodCall([NotNull] MethodInfo method, [NotNull] ReadOnlyCollection arguments) + private Expression? VisitArrayMethodCall([NotNull] MethodInfo method, [NotNull] ReadOnlyCollection arguments) { var array = arguments[0]; @@ -213,7 +214,7 @@ predicateArguments[0] is ParameterExpression parameterExpression2 && { return _sqlExpressionFactory.Overlaps( (SqlExpression)Visit(arguments[0]), - (SqlExpression)Visit(wherePredicateMethodCall.Object)); + (SqlExpression)Visit(wherePredicateMethodCall.Object!)); } } @@ -234,7 +235,10 @@ predicateArguments[0] is ParameterExpression parameterExpression2 && item)); } - static bool TryMatchEquality(Expression expression, out Expression left, out Expression right) + static bool TryMatchEquality( + Expression expression, + [CA.NotNullWhen(true)] out Expression? left, + [CA.NotNullWhen(true)] out Expression? right) { if (expression is BinaryExpression binary) { @@ -252,7 +256,7 @@ static bool TryMatchEquality(Expression expression, out Expression left, out Exp if (methodCall.Method.Name == nameof(object.Equals) && methodCall.Arguments.Count == 1) { - (left, right) = (methodCall.Object, methodCall.Arguments[0]); + (left, right) = (methodCall.Object!, methodCall.Arguments[0]); return true; } } @@ -305,7 +309,7 @@ predicateArguments[0] is ParameterExpression parameterExpression2 && { return _sqlExpressionFactory.ContainedBy( (SqlExpression)Visit(arguments[0]), - (SqlExpression)Visit(wherePredicateMethodCall.Object)); + (SqlExpression)Visit(wherePredicateMethodCall.Object!)); } } } @@ -357,7 +361,7 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) } var subtraction = _sqlExpressionFactory.MakeBinary( - ExpressionType.Subtract, sqlLeft, sqlRight, _typeMappingSource.FindMapping(typeof(int))); + ExpressionType.Subtract, sqlLeft!, sqlRight!, _typeMappingSource.FindMapping(typeof(int)))!; return PostgresFunctionExpression.CreateWithNamedArguments( "MAKE_INTERVAL", @@ -366,7 +370,7 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) nullable: true, argumentsPropagateNullability: TrueArrays[1], builtIn: true, - _nodaTimePeriodType ??= binaryExpression.Left.Type.Assembly.GetType("NodaTime.Period"), + _nodaTimePeriodType ??= binaryExpression.Left.Type.Assembly.GetType("NodaTime.Period")!, typeMapping: null); } @@ -386,7 +390,7 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) { return _sqlExpressionFactory.Function( "get_byte", - new[] { sqlLeft, sqlRight }, + new[] { sqlLeft!, sqlRight! }, nullable: true, argumentsPropagateNullability: TrueArrays[2], typeof(byte)); @@ -394,9 +398,9 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) return // Try translating ArrayIndex inside json column - _jsonPocoTranslator.TranslateMemberAccess(sqlLeft, sqlRight, binaryExpression.Type) ?? + _jsonPocoTranslator.TranslateMemberAccess(sqlLeft!, sqlRight!, binaryExpression.Type) ?? // Other types should be subscriptable - but PostgreSQL arrays are 1-based, so adjust the index. - _sqlExpressionFactory.ArrayIndex(sqlLeft, GenerateOneBasedIndexExpression(sqlRight)); + _sqlExpressionFactory.ArrayIndex(sqlLeft!, GenerateOneBasedIndexExpression(sqlRight!)); } return base.VisitBinary(binaryExpression); @@ -443,7 +447,7 @@ bool TryTranslateArguments(out SqlExpression[] sqlArguments) return false; } - sqlArguments[i] = sqlArgument; + sqlArguments[i] = sqlArgument!; } return true; @@ -493,7 +497,7 @@ static Expression TryRemoveImplicitConvert(Expression expression) [DebuggerStepThrough] - bool TranslationFailed(Expression original, Expression translation, out SqlExpression castTranslation) + private static bool TranslationFailed(Expression? original, Expression? translation, out SqlExpression? castTranslation) { if (original != null && !(translation is SqlExpression)) { diff --git a/src/EFCore.PG/Query/NpgsqlSqlExpressionFactory.cs b/src/EFCore.PG/Query/NpgsqlSqlExpressionFactory.cs index cde6040b15..7f46140f81 100644 --- a/src/EFCore.PG/Query/NpgsqlSqlExpressionFactory.cs +++ b/src/EFCore.PG/Query/NpgsqlSqlExpressionFactory.cs @@ -12,24 +12,23 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal; using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping; using Npgsql.EntityFrameworkCore.PostgreSQL.Utilities; +using CA = System.Diagnostics.CodeAnalysis; namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query { public class NpgsqlSqlExpressionFactory : SqlExpressionFactory { - readonly IRelationalTypeMappingSource _typeMappingSource; - readonly RelationalTypeMapping _boolTypeMapping; - readonly RelationalTypeMapping _intTypeMapping; + private readonly IRelationalTypeMappingSource _typeMappingSource; + private readonly RelationalTypeMapping _boolTypeMapping; - static Type _nodaTimeDurationType; - static Type _nodaTimePeriodType; + private static Type? _nodaTimeDurationType; + private static Type? _nodaTimePeriodType; public NpgsqlSqlExpressionFactory([NotNull] SqlExpressionFactoryDependencies dependencies) : base(dependencies) { _typeMappingSource = dependencies.TypeMappingSource; - _boolTypeMapping = _typeMappingSource.FindMapping(typeof(bool)); - _intTypeMapping = _typeMappingSource.FindMapping(typeof(int)); + _boolTypeMapping = _typeMappingSource.FindMapping(typeof(bool))!; } #region Expression factory methods @@ -53,7 +52,7 @@ public virtual PostgresAllExpression All( public virtual PostgresArrayIndexExpression ArrayIndex( [NotNull] SqlExpression array, [NotNull] SqlExpression index, - [CanBeNull] RelationalTypeMapping typeMapping = null) + [CanBeNull] RelationalTypeMapping? typeMapping = null) { if (!array.Type.TryGetElementType(out var elementType)) throw new ArgumentException("Array expression must be of an array or List<> type", nameof(array)); @@ -67,11 +66,11 @@ public virtual PostgresBinaryExpression AtTimeZone( [NotNull] SqlExpression timestamp, [NotNull] SqlExpression timeZone, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping = null) + [CanBeNull] RelationalTypeMapping? typeMapping = null) { // PostgreSQL AT TIME ZONE flips the given type from timestamptz to timestamp and vice versa // See https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT - typeMapping ??= FlipTimestampTypeMapping(timestamp.TypeMapping ?? _typeMappingSource.FindMapping(timestamp.Type)); + typeMapping ??= FlipTimestampTypeMapping(timestamp.TypeMapping ?? _typeMappingSource.FindMapping(timestamp.Type)!); return new PostgresBinaryExpression( PostgresExpressionType.AtTimeZone, @@ -83,10 +82,10 @@ public virtual PostgresBinaryExpression AtTimeZone( RelationalTypeMapping FlipTimestampTypeMapping(RelationalTypeMapping mapping) { var storeType = mapping.StoreType; - if (storeType.StartsWith("timestamp with time zone") || storeType.StartsWith("timestamptz")) - return _typeMappingSource.FindMapping("timestamp without time zone"); - if (storeType.StartsWith("timestamp without time zone") || storeType.StartsWith("timestamp")) - return _typeMappingSource.FindMapping("timestamp with time zone"); + if (storeType.StartsWith("timestamp with time zone", StringComparison.Ordinal) || storeType.StartsWith("timestamptz", StringComparison.Ordinal)) + return _typeMappingSource.FindMapping("timestamp without time zone")!; + if (storeType.StartsWith("timestamp without time zone", StringComparison.Ordinal) || storeType.StartsWith("timestamp", StringComparison.Ordinal)) + return _typeMappingSource.FindMapping("timestamp with time zone")!; throw new ArgumentException($"timestamp argument to AtTimeZone had unknown store type {storeType}", nameof(timestamp)); } } @@ -94,14 +93,14 @@ RelationalTypeMapping FlipTimestampTypeMapping(RelationalTypeMapping mapping) public virtual PostgresILikeExpression ILike( [NotNull] SqlExpression match, [NotNull] SqlExpression pattern, - [CanBeNull] SqlExpression escapeChar = null) + [CanBeNull] SqlExpression? escapeChar = null) => (PostgresILikeExpression)ApplyDefaultTypeMapping(new PostgresILikeExpression(match, pattern, escapeChar, null)); public virtual PostgresJsonTraversalExpression JsonTraversal( [NotNull] SqlExpression expression, bool returnsText, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping = null) + [CanBeNull] RelationalTypeMapping? typeMapping = null) => JsonTraversal(expression, Array.Empty(), returnsText, type, typeMapping); public virtual PostgresJsonTraversalExpression JsonTraversal( @@ -109,10 +108,10 @@ public virtual PostgresJsonTraversalExpression JsonTraversal( [NotNull] IEnumerable path, bool returnsText, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping = null) + [CanBeNull] RelationalTypeMapping? typeMapping = null) => new( ApplyDefaultTypeMapping(expression), - path.Select(ApplyDefaultTypeMapping).ToArray(), + path.Select(ApplyDefaultTypeMapping).ToArray()!, returnsText, type, typeMapping); @@ -124,7 +123,7 @@ public virtual PostgresJsonTraversalExpression JsonTraversal( public virtual SqlExpression NewArrayOrConstant( [NotNull] IReadOnlyList expressions, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping = null) + [CanBeNull] RelationalTypeMapping? typeMapping = null) { if (!type.TryGetElementType(out var elementType)) throw new ArgumentException($"{type.Name} isn't an array or generic List", nameof(type)); @@ -143,14 +142,14 @@ public virtual SqlExpression NewArrayOrConstant( public virtual PostgresNewArrayExpression NewArray( [NotNull] IReadOnlyList expressions, [NotNull] Type type, - [CanBeNull] RelationalTypeMapping typeMapping = null) + [CanBeNull] RelationalTypeMapping? typeMapping = null) => (PostgresNewArrayExpression)ApplyTypeMapping(new PostgresNewArrayExpression(expressions, type, typeMapping), typeMapping); - public override SqlBinaryExpression MakeBinary( + public override SqlBinaryExpression? MakeBinary( ExpressionType operatorType, SqlExpression left, SqlExpression right, - RelationalTypeMapping typeMapping) + RelationalTypeMapping? typeMapping) { Check.NotNull(left, nameof(left)); Check.NotNull(right, nameof(right)); @@ -169,7 +168,7 @@ public override SqlBinaryExpression MakeBinary( { _nodaTimeDurationType ??= left.Type.Assembly.GetType("NodaTime.Duration"); return (SqlBinaryExpression)ApplyTypeMapping( - new SqlBinaryExpression(operatorType, left, right, _nodaTimeDurationType, null), typeMapping); + new SqlBinaryExpression(operatorType, left, right, _nodaTimeDurationType!, null), typeMapping); } if (left.Type.FullName == "NodaTime.LocalDateTime" && right.Type.FullName == "NodaTime.LocalDateTime" || @@ -177,7 +176,7 @@ public override SqlBinaryExpression MakeBinary( { _nodaTimePeriodType ??= left.Type.Assembly.GetType("NodaTime.Period"); return (SqlBinaryExpression)ApplyTypeMapping( - new SqlBinaryExpression(operatorType, left, right, _nodaTimePeriodType, null), typeMapping); + new SqlBinaryExpression(operatorType, left, right, _nodaTimePeriodType!, null), typeMapping); } if (left.Type.FullName == "NodaTime.LocalDate" && right.Type.FullName == "NodaTime.LocalDate") @@ -194,7 +193,7 @@ public virtual PostgresBinaryExpression MakePostgresBinary( PostgresExpressionType operatorType, [NotNull] SqlExpression left, [NotNull] SqlExpression right, - [CanBeNull] RelationalTypeMapping typeMapping = null) + [CanBeNull] RelationalTypeMapping? typeMapping = null) { Check.NotNull(left, nameof(left)); Check.NotNull(right, nameof(right)); @@ -251,7 +250,8 @@ public virtual PostgresBinaryExpression Overlaps([NotNull] SqlExpression left, [ #endregion Expression factory methods - public override SqlExpression ApplyTypeMapping(SqlExpression sqlExpression, RelationalTypeMapping typeMapping) + [return: CA.NotNullIfNotNull("sqlExpression")] + public override SqlExpression? ApplyTypeMapping(SqlExpression? sqlExpression, RelationalTypeMapping? typeMapping) => sqlExpression == null || sqlExpression.TypeMapping != null ? sqlExpression : sqlExpression switch @@ -271,7 +271,7 @@ public override SqlExpression ApplyTypeMapping(SqlExpression sqlExpression, Rela _ => base.ApplyTypeMapping(sqlExpression, typeMapping) }; - SqlExpression ApplyTypeMappingOnSqlBinary(SqlBinaryExpression binary, RelationalTypeMapping typeMapping) + private SqlExpression ApplyTypeMappingOnSqlBinary(SqlBinaryExpression binary, RelationalTypeMapping? typeMapping) { // The default SqlExpressionFactory behavior is to assume that the two added operands have the same type, // and so to infer one side's mapping from the other if needed. Here we take care of some heterogeneous @@ -337,7 +337,7 @@ SqlExpression ApplyTypeMappingOnSqlBinary(SqlBinaryExpression binary, Relational return base.ApplyTypeMapping(binary, typeMapping); } - SqlExpression ApplyTypeMappingOnRegexMatch(PostgresRegexMatchExpression postgresRegexMatchExpression) + private SqlExpression ApplyTypeMappingOnRegexMatch(PostgresRegexMatchExpression postgresRegexMatchExpression) { var inferredTypeMapping = ExpressionExtensions.InferTypeMapping( postgresRegexMatchExpression.Match, postgresRegexMatchExpression.Pattern) @@ -350,22 +350,22 @@ SqlExpression ApplyTypeMappingOnRegexMatch(PostgresRegexMatchExpression postgres _boolTypeMapping); } - SqlExpression ApplyTypeMappingOnAny(PostgresAnyExpression postgresAnyExpression) + private SqlExpression ApplyTypeMappingOnAny(PostgresAnyExpression postgresAnyExpression) { var (item, array) = ApplyTypeMappingsOnItemAndArray(postgresAnyExpression.Item, postgresAnyExpression.Array); return new PostgresAnyExpression(item, array, postgresAnyExpression.OperatorType, _boolTypeMapping); } - SqlExpression ApplyTypeMappingOnAll(PostgresAllExpression postgresAllExpression) + private SqlExpression ApplyTypeMappingOnAll(PostgresAllExpression postgresAllExpression) { var (item, array) = ApplyTypeMappingsOnItemAndArray(postgresAllExpression.Item, postgresAllExpression.Array); return new PostgresAllExpression(item, array, postgresAllExpression.OperatorType, _boolTypeMapping); } - (SqlExpression, SqlExpression) ApplyTypeMappingsOnItemAndArray(SqlExpression itemExpression, SqlExpression arrayExpression) + private (SqlExpression, SqlExpression) ApplyTypeMappingsOnItemAndArray(SqlExpression itemExpression, SqlExpression arrayExpression) { // Attempt type inference either from the operand to the array or the other way around - var arrayMapping = (NpgsqlArrayTypeMapping)arrayExpression.TypeMapping; + var arrayMapping = (NpgsqlArrayTypeMapping?)arrayExpression.TypeMapping; var itemMapping = itemExpression.TypeMapping ?? @@ -386,7 +386,7 @@ SqlExpression ApplyTypeMappingOnAll(PostgresAllExpression postgresAllExpression) // First, special-case arrays of objects, not taking the array CLR type into account in the lookup (it would never succeed) if (arrayExpression.Type == typeof(object[]) || arrayExpression.Type == typeof(List)) { - arrayMapping = (NpgsqlArrayTypeMapping)_typeMappingSource.FindMapping(itemMapping.StoreType + "[]"); + arrayMapping = (NpgsqlArrayTypeMapping?)_typeMappingSource.FindMapping(itemMapping.StoreType + "[]"); } else { @@ -394,7 +394,7 @@ SqlExpression ApplyTypeMappingOnAll(PostgresAllExpression postgresAllExpression) // Note that we provide both the array CLR type *and* an array store type constructed from the element's store type. // If we use only the array CLR type, byte[] will yield bytea which we don't want. arrayMapping = - (NpgsqlArrayTypeMapping)_typeMappingSource.FindMapping(arrayExpression.Type, itemMapping.StoreType + "[]"); + (NpgsqlArrayTypeMapping?)_typeMappingSource.FindMapping(arrayExpression.Type, itemMapping.StoreType + "[]"); // If we failed, and the item mapping has a value converter, construct an array mapping directly over it - this will // build the corresponding array type converter @@ -415,8 +415,8 @@ SqlExpression ApplyTypeMappingOnAll(PostgresAllExpression postgresAllExpression) return (ApplyTypeMapping(itemExpression, itemMapping), ApplyTypeMapping(arrayExpression, arrayMapping)); } - SqlExpression ApplyTypeMappingOnArrayIndex( - PostgresArrayIndexExpression postgresArrayIndexExpression, RelationalTypeMapping typeMapping) + private SqlExpression ApplyTypeMappingOnArrayIndex( + PostgresArrayIndexExpression postgresArrayIndexExpression, RelationalTypeMapping? typeMapping) => new PostgresArrayIndexExpression( // TODO: Infer the array's mapping from the element ApplyDefaultTypeMapping(postgresArrayIndexExpression.Array), @@ -427,7 +427,7 @@ postgresArrayIndexExpression.Array.TypeMapping is NpgsqlArrayTypeMapping arrayMa ? arrayMapping.ElementMapping : typeMapping ?? _typeMappingSource.FindMapping(postgresArrayIndexExpression.Type)); - SqlExpression ApplyTypeMappingOnILike(PostgresILikeExpression ilikeExpression) + private SqlExpression ApplyTypeMappingOnILike(PostgresILikeExpression ilikeExpression) { var inferredTypeMapping = (ilikeExpression.EscapeChar == null ? ExpressionExtensions.InferTypeMapping( @@ -444,15 +444,15 @@ SqlExpression ApplyTypeMappingOnILike(PostgresILikeExpression ilikeExpression) _boolTypeMapping); } - SqlExpression ApplyTypeMappingOnPostgresBinary( - PostgresBinaryExpression postgresBinaryExpression, RelationalTypeMapping typeMapping) + private SqlExpression ApplyTypeMappingOnPostgresBinary( + PostgresBinaryExpression postgresBinaryExpression, RelationalTypeMapping? typeMapping) { var left = postgresBinaryExpression.Left; var right = postgresBinaryExpression.Right; Type resultType; - RelationalTypeMapping resultTypeMapping; - RelationalTypeMapping inferredTypeMapping; + RelationalTypeMapping? resultTypeMapping; + RelationalTypeMapping? inferredTypeMapping; var operatorType = postgresBinaryExpression.OperatorType; switch (operatorType) { @@ -539,14 +539,14 @@ SqlExpression ApplyTypeMappingOnPostgresBinary( } } - SqlExpression ApplyTypeMappingOnPostgresNewArray( - PostgresNewArrayExpression postgresNewArrayExpression, RelationalTypeMapping typeMapping) + private SqlExpression ApplyTypeMappingOnPostgresNewArray( + PostgresNewArrayExpression postgresNewArrayExpression, RelationalTypeMapping? typeMapping) { var arrayTypeMapping = typeMapping as NpgsqlArrayTypeMapping; if (arrayTypeMapping is null && typeMapping != null) throw new ArgumentException($"Type mapping {typeMapping.GetType().Name} isn't an {nameof(NpgsqlArrayTypeMapping)}"); - RelationalTypeMapping elementTypeMapping = null; + RelationalTypeMapping? elementTypeMapping = null; // First, loop over the expressions to infer the array's type mapping (if not provided), and to make // sure we don't have heterogeneous mappings. @@ -583,7 +583,7 @@ SqlExpression ApplyTypeMappingOnPostgresNewArray( { // An element type mapping was successfully inferred from one of the expressions (there was a column). // Infer the array's type mapping from it. - arrayTypeMapping = (NpgsqlArrayTypeMapping)_typeMappingSource.FindMapping( + arrayTypeMapping = (NpgsqlArrayTypeMapping?)_typeMappingSource.FindMapping( postgresNewArrayExpression.Type, elementTypeMapping.StoreType + "[]"); @@ -596,7 +596,7 @@ SqlExpression ApplyTypeMappingOnPostgresNewArray( } // Now go over all expressions and apply the inferred element type mapping - List newExpressions = null; + List? newExpressions = null; for (var i = 0; i < postgresNewArrayExpression.Expressions.Count; i++) { var expression = postgresNewArrayExpression.Expressions[i]; diff --git a/src/EFCore.PG/Scaffolding/Internal/DbDataReaderExtension.cs b/src/EFCore.PG/Scaffolding/Internal/DbDataReaderExtension.cs index de7856ab92..55fcead3e0 100644 --- a/src/EFCore.PG/Scaffolding/Internal/DbDataReaderExtension.cs +++ b/src/EFCore.PG/Scaffolding/Internal/DbDataReaderExtension.cs @@ -2,11 +2,9 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -#nullable enable - namespace Npgsql.EntityFrameworkCore.PostgreSQL.Scaffolding.Internal { - static class DbDataReaderExtension + internal static class DbDataReaderExtension { [DebuggerStepThrough] [return: MaybeNull] diff --git a/src/EFCore.PG/Scaffolding/Internal/NpgsqlCodeGenerator.cs b/src/EFCore.PG/Scaffolding/Internal/NpgsqlCodeGenerator.cs index 4c650add98..2298831f36 100644 --- a/src/EFCore.PG/Scaffolding/Internal/NpgsqlCodeGenerator.cs +++ b/src/EFCore.PG/Scaffolding/Internal/NpgsqlCodeGenerator.cs @@ -19,7 +19,7 @@ public NpgsqlCodeGenerator([NotNull] ProviderCodeGeneratorDependencies dependenc public override MethodCallCodeFragment GenerateUseProvider( string connectionString, - MethodCallCodeFragment providerOptions) + MethodCallCodeFragment? providerOptions) => new( nameof(NpgsqlDbContextOptionsBuilderExtensions.UseNpgsql), providerOptions == null diff --git a/src/EFCore.PG/Scaffolding/Internal/NpgsqlDatabaseModelFactory.cs b/src/EFCore.PG/Scaffolding/Internal/NpgsqlDatabaseModelFactory.cs index 2013239ecc..3018901350 100644 --- a/src/EFCore.PG/Scaffolding/Internal/NpgsqlDatabaseModelFactory.cs +++ b/src/EFCore.PG/Scaffolding/Internal/NpgsqlDatabaseModelFactory.cs @@ -20,8 +20,6 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata.Internal; using Npgsql.EntityFrameworkCore.PostgreSQL.Utilities; -#nullable enable - namespace Npgsql.EntityFrameworkCore.PostgreSQL.Scaffolding.Internal { /// @@ -232,7 +230,7 @@ ns.nspname NOT IN ({internalSchemas}) AND var name = reader.GetString("relname"); var comment = reader.GetValueOrDefault("description"); - var table = new DatabaseTable() + var table = new DatabaseTable { Database = databaseModel, Name = name, diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayArrayTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayArrayTypeMapping.cs index f046bb8724..67c8605d86 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayArrayTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayArrayTypeMapping.cs @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.ValueConversion; +using CA = System.Diagnostics.CodeAnalysis; namespace Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping { @@ -49,7 +50,7 @@ elementMapping.Converter is ValueConverter elementConverter typeof(NpgsqlArrayConverter<,>).MakeGenericType( elementConverter.ModelClrType.MakeArrayType(), elementConverter.ProviderClrType.MakeArrayType()), - elementConverter) + elementConverter)! : null, CreateComparer(elementMapping, arrayType)), storeType @@ -85,10 +86,10 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p #region Value comparer - static ValueComparer CreateComparer(RelationalTypeMapping elementMapping, Type arrayType) + private static ValueComparer? CreateComparer(RelationalTypeMapping elementMapping, Type arrayType) { Debug.Assert(arrayType.IsArray); - var elementType = arrayType.GetElementType(); + var elementType = arrayType.GetElementType()!; var unwrappedType = elementType.UnwrapNullableType(); // We currently don't support mapping multi-dimensional arrays. @@ -99,10 +100,10 @@ static ValueComparer CreateComparer(RelationalTypeMapping elementMapping, Type a elementType == unwrappedType ? typeof(SingleDimensionalArrayComparer<>).MakeGenericType(elementType) : typeof(NullableSingleDimensionalArrayComparer<>).MakeGenericType(unwrappedType), - elementMapping); + elementMapping)!; } - sealed class SingleDimensionalArrayComparer : ValueComparer + private sealed class SingleDimensionalArrayComparer : ValueComparer { public SingleDimensionalArrayComparer(RelationalTypeMapping elementMapping) : base( (a, b) => Compare(a, b, (ValueComparer)elementMapping.Comparer), @@ -111,10 +112,17 @@ public SingleDimensionalArrayComparer(RelationalTypeMapping elementMapping) : ba public override Type Type => typeof(TElem[]); - static bool Compare(TElem[] a, TElem[] b, ValueComparer elementComparer) + private static bool Compare(TElem[]? a, TElem[]? b, ValueComparer elementComparer) { - if (a.Length != b.Length) + if (a is null) + { + return b is null; + } + + if (b is null || a.Length != b.Length) + { return false; + } // Note: the following currently boxes every element access because ValueComparer isn't really // generic (see https://github.com/aspnet/EntityFrameworkCore/issues/11072) @@ -125,7 +133,7 @@ static bool Compare(TElem[] a, TElem[] b, ValueComparer elementComparer) return true; } - static int GetHashCode(TElem[] source, ValueComparer elementComparer) + private static int GetHashCode(TElem[] source, ValueComparer elementComparer) { var hash = new HashCode(); foreach (var el in source) @@ -133,7 +141,8 @@ static int GetHashCode(TElem[] source, ValueComparer elementComparer) return hash.ToHashCode(); } - static TElem[] Snapshot(TElem[] source, ValueComparer elementComparer) + [return: CA.NotNullIfNotNull("source")] + private static TElem[]? Snapshot(TElem[]? source, ValueComparer elementComparer) { if (source == null) return null; @@ -142,12 +151,12 @@ static TElem[] Snapshot(TElem[] source, ValueComparer elementComparer) // Note: the following currently boxes every element access because ValueComparer isn't really // generic (see https://github.com/aspnet/EntityFrameworkCore/issues/11072) for (var i = 0; i < source.Length; i++) - snapshot[i] = elementComparer.Snapshot(source[i]); + snapshot[i] = elementComparer.Snapshot(source[i])!; // TODO: https://github.com/dotnet/efcore/pull/24410 return snapshot; } } - sealed class NullableSingleDimensionalArrayComparer : ValueComparer + private sealed class NullableSingleDimensionalArrayComparer : ValueComparer where TElem : struct { public NullableSingleDimensionalArrayComparer(RelationalTypeMapping elementMapping) : base( @@ -157,10 +166,17 @@ public NullableSingleDimensionalArrayComparer(RelationalTypeMapping elementMappi public override Type Type => typeof(TElem?[]); - static bool Compare(TElem?[] a, TElem?[] b, ValueComparer elementComparer) + private static bool Compare(TElem?[]? a, TElem?[]? b, ValueComparer elementComparer) { - if (a.Length != b.Length) + if (a is null) + { + return b is null; + } + + if (b is null || a.Length != b.Length) + { return false; + } // Note: the following currently boxes every element access because ValueComparer isn't really // generic (see https://github.com/aspnet/EntityFrameworkCore/issues/11072) @@ -180,7 +196,7 @@ static bool Compare(TElem?[] a, TElem?[] b, ValueComparer elementComparer return true; } - static int GetHashCode(TElem?[] source, ValueComparer elementComparer) + private static int GetHashCode(TElem?[] source, ValueComparer elementComparer) { var nullableEqualityComparer = new NullableEqualityComparer(elementComparer); var hash = new HashCode(); @@ -189,7 +205,8 @@ static int GetHashCode(TElem?[] source, ValueComparer elementComparer) return hash.ToHashCode(); } - static TElem?[] Snapshot(TElem?[] source, ValueComparer elementComparer) + [return: CA.NotNullIfNotNull("source")] + private static TElem?[]? Snapshot(TElem?[]? source, ValueComparer elementComparer) { if (source == null) return null; diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayListTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayListTypeMapping.cs index 84c71871bd..15067155ce 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayListTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayListTypeMapping.cs @@ -48,7 +48,7 @@ elementMapping.Converter is ValueConverter elementConverter typeof(NpgsqlArrayConverter<,>).MakeGenericType( typeof(List<>).MakeGenericType(elementConverter.ModelClrType), elementConverter.ProviderClrType.MakeArrayType()), - elementConverter) + elementConverter)! : null, CreateComparer(elementMapping, listType)), storeType @@ -84,7 +84,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p // However, a limitation in EF Core prevents us from merging the code together, see // https://github.com/aspnet/EntityFrameworkCore/issues/11077 - static ValueComparer CreateComparer(RelationalTypeMapping elementMapping, Type listType) + private static ValueComparer CreateComparer(RelationalTypeMapping elementMapping, Type listType) { Debug.Assert(listType.IsGenericType && listType.GetGenericTypeDefinition() == typeof(List<>)); @@ -95,10 +95,10 @@ static ValueComparer CreateComparer(RelationalTypeMapping elementMapping, Type l elementType == unwrappedType ? typeof(ListComparer<>).MakeGenericType(elementType) : typeof(NullableListComparer<>).MakeGenericType(unwrappedType), - elementMapping); + elementMapping)!; } - sealed class ListComparer : ValueComparer> + private sealed class ListComparer : ValueComparer> { public ListComparer(RelationalTypeMapping elementMapping) : base( @@ -108,10 +108,17 @@ public ListComparer(RelationalTypeMapping elementMapping) public override Type Type => typeof(List); - static bool Compare(List a, List b, ValueComparer elementComparer) + private static bool Compare(List? a, List? b, ValueComparer elementComparer) { - if (a.Count != b.Count) + if (a is null) + { + return b is null; + } + + if (b is null || a.Count != b.Count) + { return false; + } // Note: the following currently boxes every element access because ValueComparer isn't really // generic (see https://github.com/aspnet/EntityFrameworkCore/issues/11072) @@ -122,7 +129,7 @@ static bool Compare(List a, List b, ValueComparer elementCo return true; } - static int GetHashCode(List source, ValueComparer elementComparer) + private static int GetHashCode(List source, ValueComparer elementComparer) { var hash = new HashCode(); foreach (var el in source) @@ -130,7 +137,7 @@ static int GetHashCode(List source, ValueComparer elementComparer) return hash.ToHashCode(); } - static List Snapshot(List source, ValueComparer elementComparer) + private static List? Snapshot(List? source, ValueComparer elementComparer) { if (source == null) return null; @@ -140,13 +147,13 @@ static List Snapshot(List source, ValueComparer elementComp // Note: the following currently boxes every element access because ValueComparer isn't really // generic (see https://github.com/aspnet/EntityFrameworkCore/issues/11072) foreach (var e in source) - snapshot.Add(elementComparer.Snapshot(e)); + snapshot.Add(elementComparer.Snapshot(e)!); // TODO: https://github.com/dotnet/efcore/pull/24410 return snapshot; } } - sealed class NullableListComparer : ValueComparer> + private sealed class NullableListComparer : ValueComparer> where TElem : struct { public NullableListComparer(RelationalTypeMapping elementMapping) @@ -157,10 +164,17 @@ public NullableListComparer(RelationalTypeMapping elementMapping) public override Type Type => typeof(List); - static bool Compare(List a, List b, ValueComparer elementComparer) + private static bool Compare(List? a, List? b, ValueComparer elementComparer) { - if (a.Count != b.Count) + if (a is null) + { + return b is null; + } + + if (b is null || a.Count != b.Count) + { return false; + } // Note: the following currently boxes every element access because ValueComparer isn't really // generic (see https://github.com/aspnet/EntityFrameworkCore/issues/11072) @@ -180,7 +194,7 @@ static bool Compare(List a, List b, ValueComparer element return true; } - static int GetHashCode(List source, ValueComparer elementComparer) + private static int GetHashCode(List source, ValueComparer elementComparer) { var nullableEqualityComparer = new NullableEqualityComparer(elementComparer); var hash = new HashCode(); @@ -189,7 +203,7 @@ static int GetHashCode(List source, ValueComparer elementComparer return hash.ToHashCode(); } - static List Snapshot(List source, ValueComparer elementComparer) + static List? Snapshot(List? source, ValueComparer elementComparer) { if (source == null) return null; diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayTypeMapping.cs index 3969de2f0e..526a5925da 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlArrayTypeMapping.cs @@ -12,8 +12,6 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Storage.ValueConversion; using NpgsqlTypes; -#nullable enable - namespace Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.Mapping { /// diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlBitTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlBitTypeMapping.cs index b16a3f61b3..b6699efc02 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlBitTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlBitTypeMapping.cs @@ -47,6 +47,6 @@ public override Expression GenerateCodeLiteral(object value) } static readonly ConstructorInfo Constructor = - typeof(BitArray).GetConstructor(new[] { typeof(bool[]) }); + typeof(BitArray).GetConstructor(new[] { typeof(bool[]) })!; } } diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlCharacterTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlCharacterTypeMapping.cs index fefcd40997..5e463dd500 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlCharacterTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlCharacterTypeMapping.cs @@ -30,7 +30,7 @@ public class NpgsqlCharacterTypeMapping : StringTypeMapping /// value converter instead. ///

/// - [NotNull] static readonly ValueComparer CharacterValueComparer = + private static readonly ValueComparer CharacterValueComparer = new( (x, y) => EqualsWithoutTrailingWhitespace(x, y), x => GetHashCodeWithoutTrailingWhitespace(x)); @@ -71,10 +71,16 @@ protected override void ConfigureParameter(DbParameter parameter) base.ConfigureParameter(parameter); } - static bool EqualsWithoutTrailingWhitespace(string a, string b) - => a.AsSpan().TrimEnd().SequenceEqual(b.AsSpan().TrimEnd()); + private static bool EqualsWithoutTrailingWhitespace(string? a, string? b) + => (a, b) switch + { + (null, null) => true, + (_, null) => false, + (null, _) => false, + _ => a.AsSpan().TrimEnd().SequenceEqual(b.AsSpan().TrimEnd()) + }; - static int GetHashCodeWithoutTrailingWhitespace(string a) - => a?.TrimEnd().GetHashCode() ?? 0; + private static int GetHashCodeWithoutTrailingWhitespace(string a) + => a.TrimEnd().GetHashCode(); } } diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlEnumTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlEnumTypeMapping.cs index 87dc299709..3bf2ac0041 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlEnumTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlEnumTypeMapping.cs @@ -20,10 +20,10 @@ public class NpgsqlEnumTypeMapping : RelationalTypeMapping public NpgsqlEnumTypeMapping( [NotNull] string storeType, - [CanBeNull] string storeTypeSchema, + [CanBeNull] string? storeTypeSchema, [NotNull] Type enumType, [NotNull] ISqlGenerationHelper sqlGenerationHelper, - [CanBeNull] INpgsqlNameTranslator nameTranslator = null) + [CanBeNull] INpgsqlNameTranslator? nameTranslator = null) : base(sqlGenerationHelper.DelimitIdentifier(storeType, storeTypeSchema), enumType) { if (!enumType.IsEnum || !enumType.IsValueType) @@ -56,7 +56,7 @@ protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters p static Dictionary CreateValueMapping([NotNull] Type enumType, [NotNull] INpgsqlNameTranslator nameTranslator) => enumType.GetFields(BindingFlags.Static | BindingFlags.Public) .ToDictionary( - x => x.GetValue(null), + x => x.GetValue(null)!, x => x.GetCustomAttribute()?.PgName ?? nameTranslator.TranslateMemberName(x.Name)); } } diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlGeometricTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlGeometricTypeMapping.cs index 59b9d526da..5060897119 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlGeometricTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlGeometricTypeMapping.cs @@ -32,8 +32,8 @@ public override Expression GenerateCodeLiteral(object value) return Expression.New(Constructor, Expression.Constant(point.X), Expression.Constant(point.Y)); } - static readonly ConstructorInfo Constructor = - typeof(NpgsqlPoint).GetConstructor(new[] { typeof(double), typeof(double) }); + private static readonly ConstructorInfo Constructor = + typeof(NpgsqlPoint).GetConstructor(new[] { typeof(double), typeof(double) })!; } public class NpgsqlLineTypeMapping : NpgsqlTypeMapping @@ -63,8 +63,8 @@ public override Expression GenerateCodeLiteral(object value) Expression.Constant(line.A), Expression.Constant(line.B), Expression.Constant(line.C)); } - static readonly ConstructorInfo Constructor = - typeof(NpgsqlLine).GetConstructor(new[] { typeof(double), typeof(double), typeof(double) }); + private static readonly ConstructorInfo Constructor = + typeof(NpgsqlLine).GetConstructor(new[] { typeof(double), typeof(double), typeof(double) })!; } public class NpgsqlLineSegmentTypeMapping : NpgsqlTypeMapping @@ -92,8 +92,8 @@ public override Expression GenerateCodeLiteral(object value) Expression.Constant(lseg.End.X), Expression.Constant(lseg.End.Y)); } - static readonly ConstructorInfo Constructor = - typeof(NpgsqlLSeg).GetConstructor(new[] { typeof(double), typeof(double), typeof(double), typeof(double) }); + private static readonly ConstructorInfo Constructor = + typeof(NpgsqlLSeg).GetConstructor(new[] { typeof(double), typeof(double), typeof(double), typeof(double) })!; } public class NpgsqlBoxTypeMapping : NpgsqlTypeMapping @@ -121,8 +121,8 @@ public override Expression GenerateCodeLiteral(object value) Expression.Constant(box.Bottom), Expression.Constant(box.Left)); } - static readonly ConstructorInfo Constructor = - typeof(NpgsqlBox).GetConstructor(new[] { typeof(double), typeof(double), typeof(double), typeof(double) }); + private static readonly ConstructorInfo Constructor = + typeof(NpgsqlBox).GetConstructor(new[] { typeof(double), typeof(double), typeof(double), typeof(double) })!; } public class NpgsqlPathTypeMapping : NpgsqlTypeMapping @@ -168,11 +168,11 @@ public override Expression GenerateCodeLiteral(object value) Expression.Constant(path.Open)); } - static readonly ConstructorInfo Constructor = - typeof(NpgsqlPath).GetConstructor(new[] { typeof(IEnumerable), typeof(bool) }); + private static readonly ConstructorInfo Constructor = + typeof(NpgsqlPath).GetConstructor(new[] { typeof(IEnumerable), typeof(bool) })!; - static readonly ConstructorInfo PointConstructor = - typeof(NpgsqlPoint).GetConstructor(new[] { typeof(double), typeof(double) }); + private static readonly ConstructorInfo PointConstructor = + typeof(NpgsqlPoint).GetConstructor(new[] { typeof(double), typeof(double) })!; } public class NpgsqlPolygonTypeMapping : NpgsqlTypeMapping @@ -215,11 +215,11 @@ public override Expression GenerateCodeLiteral(object value) Expression.Constant(p.X), Expression.Constant(p.Y))))); } - static readonly ConstructorInfo Constructor = - typeof(NpgsqlPolygon).GetConstructor(new[] { typeof(NpgsqlPoint[]) }); + private static readonly ConstructorInfo Constructor = + typeof(NpgsqlPolygon).GetConstructor(new[] { typeof(NpgsqlPoint[]) })!; - static readonly ConstructorInfo PointConstructor = - typeof(NpgsqlPoint).GetConstructor(new[] { typeof(double), typeof(double) }); + private static readonly ConstructorInfo PointConstructor = + typeof(NpgsqlPoint).GetConstructor(new[] { typeof(double), typeof(double) })!; } public class NpgsqlCircleTypeMapping : NpgsqlTypeMapping @@ -246,7 +246,7 @@ public override Expression GenerateCodeLiteral(object value) Expression.Constant(circle.X), Expression.Constant(circle.Y), Expression.Constant(circle.Radius)); } - static readonly ConstructorInfo Constructor = - typeof(NpgsqlCircle).GetConstructor(new[] { typeof(double), typeof(double), typeof(double) }); + private static readonly ConstructorInfo Constructor = + typeof(NpgsqlCircle).GetConstructor(new[] { typeof(double), typeof(double), typeof(double) })!; } } diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlHstoreTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlHstoreTypeMapping.cs index 79f5de3d73..209bd1420a 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlHstoreTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlHstoreTypeMapping.cs @@ -59,7 +59,7 @@ protected override string GenerateNonNullSqlLiteral(object value) return sb.ToString(); } - static ValueComparer GetComparer(Type clrType) + private static ValueComparer? GetComparer(Type clrType) { if (clrType == typeof(Dictionary)) return MutableComparerInstance; @@ -84,14 +84,18 @@ public HstoreMutableComparer() : base( o => o == null ? null : new Dictionary(o)) {} - static bool Compare(Dictionary a, Dictionary b) + static bool Compare(Dictionary? a, Dictionary? b) { if (a is null) + { return b is null; - if (b is null) - return false; - if (a.Count != b.Count) + } + + if (b is null || a.Count != b.Count) + { return false; + } + foreach (var kv in a) if (!b.TryGetValue(kv.Key, out var bValue) || kv.Value != bValue) return false; diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlJsonTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlJsonTypeMapping.cs index dfe3dbe02b..b1755f0ce3 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlJsonTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlJsonTypeMapping.cs @@ -74,6 +74,6 @@ public override Expression GenerateCodeLiteral(object value) static readonly Expression DefaultJsonDocumentOptions = Expression.New(typeof(JsonDocumentOptions)); static readonly MethodInfo ParseMethod = - typeof(JsonDocument).GetMethod(nameof(JsonDocument.Parse), new[] { typeof(string), typeof(JsonDocumentOptions) }); + typeof(JsonDocument).GetMethod(nameof(JsonDocument.Parse), new[] { typeof(string), typeof(JsonDocumentOptions) })!; } } diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlNetworkTypeMappings.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlNetworkTypeMappings.cs index 4000a8ffbc..8168f29646 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlNetworkTypeMappings.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlNetworkTypeMappings.cs @@ -32,7 +32,7 @@ protected override string GenerateNonNullSqlLiteral(object value) public override Expression GenerateCodeLiteral(object value) => Expression.Call(ParseMethod, Expression.Constant(((PhysicalAddress)value).ToString())); - static readonly MethodInfo ParseMethod = typeof(PhysicalAddress).GetMethod("Parse", new[] { typeof(string) }); + static readonly MethodInfo ParseMethod = typeof(PhysicalAddress).GetMethod("Parse", new[] { typeof(string) })!; } /// @@ -60,7 +60,7 @@ protected override string GenerateNonNullSqlLiteral(object value) public override Expression GenerateCodeLiteral(object value) => Expression.Call(ParseMethod, Expression.Constant(((PhysicalAddress)value).ToString())); - static readonly MethodInfo ParseMethod = typeof(PhysicalAddress).GetMethod("Parse", new[] { typeof(string) }); + static readonly MethodInfo ParseMethod = typeof(PhysicalAddress).GetMethod("Parse", new[] { typeof(string) })!; } /// @@ -88,7 +88,7 @@ protected override string GenerateNonNullSqlLiteral(object value) public override Expression GenerateCodeLiteral(object value) => Expression.Call(ParseMethod, Expression.Constant(((IPAddress)value).ToString())); - static readonly MethodInfo ParseMethod = typeof(IPAddress).GetMethod("Parse", new[] { typeof(string) }); + static readonly MethodInfo ParseMethod = typeof(IPAddress).GetMethod("Parse", new[] { typeof(string) })!; } /// @@ -125,9 +125,9 @@ public override Expression GenerateCodeLiteral(object value) Expression.Constant(cidr.Subnet)); } - static readonly MethodInfo ParseMethod = typeof(IPAddress).GetMethod("Parse", new[] { typeof(string) }); + static readonly MethodInfo ParseMethod = typeof(IPAddress).GetMethod("Parse", new[] { typeof(string) })!; static readonly ConstructorInfo Constructor = - typeof((IPAddress, int)).GetConstructor(new[] { typeof(IPAddress), typeof(int) }); + typeof((IPAddress, int)).GetConstructor(new[] { typeof(IPAddress), typeof(int) })!; } } diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlRangeTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlRangeTypeMapping.cs index 566d7abe09..8e1fa8b0a5 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlRangeTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlRangeTypeMapping.cs @@ -48,7 +48,7 @@ public NpgsqlRangeTypeMapping( /// The SQL generation helper to delimit the store name. public NpgsqlRangeTypeMapping( [NotNull] string storeType, - [CanBeNull] string storeTypeSchema, + [CanBeNull] string? storeTypeSchema, [NotNull] Type clrType, [NotNull] RelationalTypeMapping subtypeMapping, [NotNull] ISqlGenerationHelper sqlGenerationHelper) @@ -99,16 +99,16 @@ public override Expression GenerateCodeLiteral(object value) var subtypeType = SubtypeMapping.ClrType; var rangeType = typeof(NpgsqlRange<>).MakeGenericType(subtypeType); - var lower = rangeType.GetProperty(nameof(NpgsqlRange.LowerBound)).GetValue(value); - var upper = rangeType.GetProperty(nameof(NpgsqlRange.UpperBound)).GetValue(value); - var lowerInfinite = (bool)rangeType.GetProperty(nameof(NpgsqlRange.LowerBoundInfinite)).GetValue(value); - var upperInfinite = (bool)rangeType.GetProperty(nameof(NpgsqlRange.UpperBoundInfinite)).GetValue(value); - var lowerInclusive = (bool)rangeType.GetProperty(nameof(NpgsqlRange.LowerBoundIsInclusive)).GetValue(value); - var upperInclusive = (bool)rangeType.GetProperty(nameof(NpgsqlRange.UpperBoundIsInclusive)).GetValue(value); + var lower = rangeType.GetProperty(nameof(NpgsqlRange.LowerBound))!.GetValue(value); + var upper = rangeType.GetProperty(nameof(NpgsqlRange.UpperBound))!.GetValue(value); + var lowerInfinite = (bool)rangeType.GetProperty(nameof(NpgsqlRange.LowerBoundInfinite))!.GetValue(value)!; + var upperInfinite = (bool)rangeType.GetProperty(nameof(NpgsqlRange.UpperBoundInfinite))!.GetValue(value)!; + var lowerInclusive = (bool)rangeType.GetProperty(nameof(NpgsqlRange.LowerBoundIsInclusive))!.GetValue(value)!; + var upperInclusive = (bool)rangeType.GetProperty(nameof(NpgsqlRange.UpperBoundIsInclusive))!.GetValue(value)!; return lowerInfinite || upperInfinite ? Expression.New( - rangeType.GetConstructor(new[] { subtypeType, typeof(bool), typeof(bool), subtypeType, typeof(bool), typeof(bool) }), + rangeType.GetConstructor(new[] { subtypeType, typeof(bool), typeof(bool), subtypeType, typeof(bool), typeof(bool) })!, Expression.Constant(lower), Expression.Constant(lowerInclusive), Expression.Constant(lowerInfinite), @@ -116,7 +116,7 @@ public override Expression GenerateCodeLiteral(object value) Expression.Constant(upperInclusive), Expression.Constant(upperInfinite)) : Expression.New( - rangeType.GetConstructor(new[] { subtypeType, typeof(bool), subtypeType, typeof(bool) }), + rangeType.GetConstructor(new[] { subtypeType, typeof(bool), subtypeType, typeof(bool) })!, Expression.Constant(lower), Expression.Constant(lowerInclusive), Expression.Constant(upper), diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlTidTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlTidTypeMapping.cs index 9ccb6c9528..5e8f2d6e09 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlTidTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlTidTypeMapping.cs @@ -35,6 +35,6 @@ public override Expression GenerateCodeLiteral(object value) } static readonly ConstructorInfo Constructor = - typeof(NpgsqlTid).GetConstructor(new[] { typeof(uint), typeof(ushort) }); + typeof(NpgsqlTid).GetConstructor(new[] { typeof(uint), typeof(ushort) })!; } } diff --git a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlVarbitTypeMapping.cs b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlVarbitTypeMapping.cs index e272f0773f..39001cd2bd 100644 --- a/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlVarbitTypeMapping.cs +++ b/src/EFCore.PG/Storage/Internal/Mapping/NpgsqlVarbitTypeMapping.cs @@ -39,6 +39,6 @@ public override Expression GenerateCodeLiteral(object value) } static readonly ConstructorInfo Constructor = - typeof(BitArray).GetConstructor(new[] { typeof(bool[]) }); + typeof(BitArray).GetConstructor(new[] { typeof(bool[]) })!; } } diff --git a/src/EFCore.PG/Storage/Internal/NpgsqlDatabaseCreator.cs b/src/EFCore.PG/Storage/Internal/NpgsqlDatabaseCreator.cs index 7c48b2b305..675e0772df 100644 --- a/src/EFCore.PG/Storage/Internal/NpgsqlDatabaseCreator.cs +++ b/src/EFCore.PG/Storage/Internal/NpgsqlDatabaseCreator.cs @@ -92,12 +92,12 @@ public override bool HasTables() null, null, Dependencies.CurrentContext.Context, - Dependencies.CommandLogger))); + Dependencies.CommandLogger))!); public override Task HasTablesAsync(CancellationToken cancellationToken = default) => Dependencies.ExecutionStrategyFactory.Create().ExecuteAsync( _connection, - async (connection, ct) => (bool)await CreateHasTablesCommand() + async (connection, ct) => (bool)(await CreateHasTablesCommand() .ExecuteScalarAsync( new RelationalCommandParameterObject( connection, @@ -105,7 +105,7 @@ public override Task HasTablesAsync(CancellationToken cancellationToken = null, Dependencies.CurrentContext.Context, Dependencies.CommandLogger), - cancellationToken: ct), cancellationToken); + cancellationToken: ct))!, cancellationToken); IRelationalCommand CreateHasTablesCommand() => _rawSqlCommandBuilder diff --git a/src/EFCore.PG/Storage/Internal/NpgsqlExecutionStrategy.cs b/src/EFCore.PG/Storage/Internal/NpgsqlExecutionStrategy.cs index 30f0a1222d..1b75ca8073 100644 --- a/src/EFCore.PG/Storage/Internal/NpgsqlExecutionStrategy.cs +++ b/src/EFCore.PG/Storage/Internal/NpgsqlExecutionStrategy.cs @@ -19,7 +19,7 @@ public NpgsqlExecutionStrategy([NotNull] ExecutionStrategyDependencies dependenc public virtual TResult Execute( TState state, Func operation, - Func> verifySucceeded) + Func>? verifySucceeded) { try { @@ -34,7 +34,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.PG/Storage/Internal/NpgsqlRelationalConnection.cs b/src/EFCore.PG/Storage/Internal/NpgsqlRelationalConnection.cs index 32f7f421b2..e0ba5ae79a 100644 --- a/src/EFCore.PG/Storage/Internal/NpgsqlRelationalConnection.cs +++ b/src/EFCore.PG/Storage/Internal/NpgsqlRelationalConnection.cs @@ -12,9 +12,9 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal { public class NpgsqlRelationalConnection : RelationalConnection, INpgsqlRelationalConnection { - private ProvideClientCertificatesCallback ProvideClientCertificatesCallback { get; } - private RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; } - private ProvidePasswordCallback ProvidePasswordCallback { get; } + private ProvideClientCertificatesCallback? ProvideClientCertificatesCallback { get; } + private RemoteCertificateValidationCallback? RemoteCertificateValidationCallback { get; } + private ProvidePasswordCallback? ProvidePasswordCallback { get; } /// /// Indicates whether the store connection supports ambient transactions @@ -27,9 +27,12 @@ public NpgsqlRelationalConnection([NotNull] RelationalConnectionDependencies dep var npgsqlOptions = dependencies.ContextOptions.Extensions.OfType().FirstOrDefault(); - ProvideClientCertificatesCallback = npgsqlOptions.ProvideClientCertificatesCallback; - RemoteCertificateValidationCallback = npgsqlOptions.RemoteCertificateValidationCallback; - ProvidePasswordCallback = npgsqlOptions.ProvidePasswordCallback; + if (npgsqlOptions is not null) + { + ProvideClientCertificatesCallback = npgsqlOptions.ProvideClientCertificatesCallback; + RemoteCertificateValidationCallback = npgsqlOptions.RemoteCertificateValidationCallback; + ProvidePasswordCallback = npgsqlOptions.ProvidePasswordCallback; + } } protected override DbConnection CreateDbConnection() @@ -74,7 +77,7 @@ public virtual INpgsqlRelationalConnection CreateMasterConnection() } // Accessing Transaction.Current is expensive, so don't do it if Enlist is false in the connection string - public override Transaction CurrentAmbientTransaction + public override Transaction? CurrentAmbientTransaction => DbConnection.Settings.Enlist ? Transaction.Current : null; public virtual NpgsqlRelationalConnection CloneWith(string connectionString) diff --git a/src/EFCore.PG/Storage/Internal/NpgsqlTransientExceptionDetector.cs b/src/EFCore.PG/Storage/Internal/NpgsqlTransientExceptionDetector.cs index 3f3b8cea91..4bcb45191e 100644 --- a/src/EFCore.PG/Storage/Internal/NpgsqlTransientExceptionDetector.cs +++ b/src/EFCore.PG/Storage/Internal/NpgsqlTransientExceptionDetector.cs @@ -8,7 +8,7 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal /// public class NpgsqlTransientExceptionDetector { - public static bool ShouldRetryOn([NotNull] Exception ex) + public static bool ShouldRetryOn([CanBeNull] Exception? ex) => (ex as NpgsqlException)?.IsTransient == true || ex is TimeoutException; } } diff --git a/src/EFCore.PG/Storage/Internal/NpgsqlTypeMappingSource.cs b/src/EFCore.PG/Storage/Internal/NpgsqlTypeMappingSource.cs index ba4371f563..95744d36b8 100644 --- a/src/EFCore.PG/Storage/Internal/NpgsqlTypeMappingSource.cs +++ b/src/EFCore.PG/Storage/Internal/NpgsqlTypeMappingSource.cs @@ -133,7 +133,7 @@ public class NpgsqlTypeMappingSource : RelationalTypeMappingSource public NpgsqlTypeMappingSource([NotNull] TypeMappingSourceDependencies dependencies, [NotNull] RelationalTypeMappingSourceDependencies relationalDependencies, [NotNull] ISqlGenerationHelper sqlGenerationHelper, - [CanBeNull] INpgsqlOptions npgsqlOptions=null) + [CanBeNull] INpgsqlOptions? npgsqlOptions = null) : base(dependencies, relationalDependencies) { _sqlGenerationHelper = Check.NotNull(sqlGenerationHelper, nameof(sqlGenerationHelper)); @@ -322,14 +322,14 @@ protected virtual void SetupEnumMappings([NotNull] ISqlGenerationHelper sqlGener } } - protected override RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo) => + protected override RelationalTypeMapping? FindMapping(in RelationalTypeMappingInfo mappingInfo) => // First, try any plugins, allowing them to override built-in mappings (e.g. NodaTime) base.FindMapping(mappingInfo) ?? FindBaseMapping(mappingInfo)?.Clone(mappingInfo) ?? FindArrayMapping(mappingInfo) ?? FindUserRangeMapping(mappingInfo); - protected virtual RelationalTypeMapping FindBaseMapping(in RelationalTypeMappingInfo mappingInfo) + protected virtual RelationalTypeMapping? FindBaseMapping(in RelationalTypeMappingInfo mappingInfo) { var clrType = mappingInfo.ClrType; var storeTypeName = mappingInfo.StoreTypeName; @@ -357,7 +357,7 @@ protected virtual RelationalTypeMapping FindBaseMapping(in RelationalTypeMapping return null; } - if (StoreTypeMappings.TryGetValue(storeTypeNameBase, out mappings)) + if (StoreTypeMappings.TryGetValue(storeTypeNameBase!, out mappings)) { if (clrType == null) return mappings[0].Clone(in mappingInfo); @@ -422,10 +422,10 @@ protected virtual RelationalTypeMapping FindBaseMapping(in RelationalTypeMapping return mapping; } - protected virtual RelationalTypeMapping FindArrayMapping(in RelationalTypeMappingInfo mappingInfo) + protected virtual RelationalTypeMapping? FindArrayMapping(in RelationalTypeMappingInfo mappingInfo) { var clrType = mappingInfo.ClrType; - Type elementClrType = null; + Type? elementClrType = null; if (clrType != null && !clrType.TryGetElementType(out elementClrType)) return null; // Not an array/list @@ -439,9 +439,9 @@ protected virtual RelationalTypeMapping FindArrayMapping(in RelationalTypeMappin return null; var elementStoreType = storeType.Substring(0, storeType.Length - 2); - var elementStoreTypeNameBase = storeTypeNameBase.Substring(0, storeTypeNameBase.Length - 2); + var elementStoreTypeNameBase = storeTypeNameBase!.Substring(0, storeTypeNameBase.Length - 2); - RelationalTypeMapping elementMapping; + RelationalTypeMapping? elementMapping; elementMapping = elementClrType == null ? FindMapping(new RelationalTypeMappingInfo( @@ -470,7 +470,7 @@ protected virtual RelationalTypeMapping FindArrayMapping(in RelationalTypeMappin var elementType = clrType.GetElementType(); Debug.Assert(elementType != null, "Detected array type but element type is null"); - var elementMapping = (RelationalTypeMapping)FindMapping(elementType); + var elementMapping = (RelationalTypeMapping?)FindMapping(elementType); // If no mapping was found for the element, there's no mapping for the array. // Also, arrays of arrays aren't supported (as opposed to multidimensional arrays) by PostgreSQL @@ -491,7 +491,7 @@ protected virtual RelationalTypeMapping FindArrayMapping(in RelationalTypeMappin var elementType = clrType.GetGenericArguments()[0]; // If an element isn't supported, neither is its array - var elementMapping = (RelationalTypeMapping)FindMapping(elementType); + var elementMapping = (RelationalTypeMapping?)FindMapping(elementType); if (elementMapping == null) return null; @@ -505,9 +505,9 @@ protected virtual RelationalTypeMapping FindArrayMapping(in RelationalTypeMappin return null; } - protected virtual RelationalTypeMapping FindUserRangeMapping(in RelationalTypeMappingInfo mappingInfo) + protected virtual RelationalTypeMapping? FindUserRangeMapping(in RelationalTypeMappingInfo mappingInfo) { - UserRangeDefinition rangeDefinition = null; + UserRangeDefinition? rangeDefinition = null; var rangeStoreType = mappingInfo.StoreTypeName; var rangeClrType = mappingInfo.ClrType; @@ -543,12 +543,12 @@ protected virtual RelationalTypeMapping FindUserRangeMapping(in RelationalTypeMa else if (rangeClrType != null) rangeDefinition = _userRangeDefinitions.SingleOrDefault(m => m.SubtypeClrType == rangeClrType.GetGenericArguments()[0]); - if (rangeDefinition == null) + if (rangeClrType is null || rangeDefinition is null) return null; // We now have a user-defined range definition from the context options. Use it to get the subtype's // mapping - var subtypeMapping = (RelationalTypeMapping)(rangeDefinition.SubtypeName == null + var subtypeMapping = (RelationalTypeMapping?)(rangeDefinition.SubtypeName == null ? FindMapping(rangeDefinition.SubtypeClrType) : FindMapping(rangeDefinition.SubtypeName)); @@ -572,8 +572,8 @@ static bool NameBasesUsesPrecision(ReadOnlySpan span) }; // We override to support parsing array store names (e.g. varchar(32)[]), timestamp(5) with time zone, etc. - protected override string ParseStoreTypeName( - string storeTypeName, + protected override string? ParseStoreTypeName( + string? storeTypeName, out bool? unicode, out int? size, out int? precision, @@ -631,7 +631,7 @@ protected override string ParseStoreTypeName( return preParens.ToString(); } - public override CoreTypeMapping FindMapping(IProperty property) + public override CoreTypeMapping? FindMapping(IProperty property) { var mapping = base.FindMapping(property); diff --git a/src/EFCore.PG/Storage/ValueConversion/NpgsqlValueConverterSelector.cs b/src/EFCore.PG/Storage/ValueConversion/NpgsqlValueConverterSelector.cs index b86cfef54d..ac892122c4 100644 --- a/src/EFCore.PG/Storage/ValueConversion/NpgsqlValueConverterSelector.cs +++ b/src/EFCore.PG/Storage/ValueConversion/NpgsqlValueConverterSelector.cs @@ -17,7 +17,7 @@ public NpgsqlValueConverterSelector([NotNull] ValueConverterSelectorDependencies : base(dependencies) {} /// - public override IEnumerable Select(Type modelClrType, Type providerClrType = null) + public override IEnumerable Select(Type modelClrType, Type? providerClrType = null) { var providerElementType = default(Type); @@ -48,7 +48,7 @@ public override IEnumerable Select(Type modelClrType, Type p typeof(NpgsqlArrayConverter<,>).MakeGenericType( modelClrType, x.ProviderArrayType), - x.ElementConverterInfo.Create())))); + x.ElementConverterInfo.Create())!))); return arrayConverters.Concat(base.Select(modelClrType, providerClrType)); } diff --git a/src/EFCore.PG/Types/LTree.cs b/src/EFCore.PG/Types/LTree.cs index ea11e4bc7f..a8f30684fb 100644 --- a/src/EFCore.PG/Types/LTree.cs +++ b/src/EFCore.PG/Types/LTree.cs @@ -144,7 +144,7 @@ public static LTree LongestCommonAncestor([NotNull] params LTree[] others) public bool Equals(LTree other) => _value == other._value; /// - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj is LTree other && Equals(other); /// diff --git a/src/EFCore.PG/Update/Internal/NpgsqlUpdateSqlGenerator.cs b/src/EFCore.PG/Update/Internal/NpgsqlUpdateSqlGenerator.cs index e16e8dd6a9..52c130e33e 100644 --- a/src/EFCore.PG/Update/Internal/NpgsqlUpdateSqlGenerator.cs +++ b/src/EFCore.PG/Update/Internal/NpgsqlUpdateSqlGenerator.cs @@ -87,7 +87,7 @@ private void AppendReturningClause( .AppendJoin(operations.Select(c => SqlGenerationHelper.DelimitIdentifier(c.ColumnName))); } - public override void AppendNextSequenceValueOperation(StringBuilder commandStringBuilder, string name, string schema) + public override void AppendNextSequenceValueOperation(StringBuilder commandStringBuilder, string name, string? schema) { commandStringBuilder.Append("SELECT nextval('"); SqlGenerationHelper.DelimitIdentifier(commandStringBuilder, Check.NotNull(name, nameof(name)), schema); diff --git a/src/EFCore.PG/Utilities/EnumerableExtensions.cs b/src/EFCore.PG/Utilities/EnumerableExtensions.cs deleted file mode 100644 index fe821b88a6..0000000000 --- a/src/EFCore.PG/Utilities/EnumerableExtensions.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Diagnostics; -using System.Linq; - -// ReSharper disable once CheckNamespace - -namespace System.Collections.Generic -{ - [DebuggerStepThrough] - internal static class EnumerableExtensions - { - public static string Join(this IEnumerable source, string separator = ", ") - { - return string.Join(separator, source); - } - - public static IEnumerable Distinct( - this IEnumerable source, Func comparer) - where T : class - { - return source.Distinct(new DynamicEqualityComparer(comparer)); - } - - private sealed class DynamicEqualityComparer : IEqualityComparer - where T : class - { - private readonly Func _func; - - public DynamicEqualityComparer(Func func) - { - _func = func; - } - - public bool Equals(T x, T y) - { - return _func(x, y); - } - - public int GetHashCode(T obj) - { - return 0; // force Equals - } - } - } -} diff --git a/src/EFCore.PG/Utilities/ReferenceNullabilityDecoder.cs b/src/EFCore.PG/Utilities/ReferenceNullabilityDecoder.cs index 59b54a3601..798d9083e5 100644 --- a/src/EFCore.PG/Utilities/ReferenceNullabilityDecoder.cs +++ b/src/EFCore.PG/Utilities/ReferenceNullabilityDecoder.cs @@ -5,8 +5,6 @@ using JetBrains.Annotations; using CA = System.Diagnostics.CodeAnalysis; -#nullable enable - namespace Npgsql.EntityFrameworkCore.PostgreSQL.Utilities { // Most of the code here is common with EF Core's NonNullableConventionBase diff --git a/src/EFCore.PG/Utilities/SortOrderHelper.cs b/src/EFCore.PG/Utilities/SortOrderHelper.cs index 59607d0399..8bc5d38fa0 100644 --- a/src/EFCore.PG/Utilities/SortOrderHelper.cs +++ b/src/EFCore.PG/Utilities/SortOrderHelper.cs @@ -7,10 +7,12 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Utilities { static class SortOrderHelper { - public static bool IsDefaultSortOrder([CanBeNull] IReadOnlyList sortOrders) + public static bool IsDefaultSortOrder([CanBeNull] IReadOnlyList? sortOrders) => sortOrders?.All(sortOrder => sortOrder == SortOrder.Ascending) ?? true; - public static bool IsDefaultNullSortOrder([CanBeNull] IReadOnlyList nullSortOrders, [CanBeNull] IReadOnlyList sortOrders) + public static bool IsDefaultNullSortOrder( + [CanBeNull] IReadOnlyList? nullSortOrders, + [CanBeNull] IReadOnlyList? sortOrders) { if (nullSortOrders == null) { diff --git a/src/EFCore.PG/ValueGeneration/Internal/NpgsqlSequenceHiLoValueGenerator.cs b/src/EFCore.PG/ValueGeneration/Internal/NpgsqlSequenceHiLoValueGenerator.cs index 114d7e5e38..dd1583e896 100644 --- a/src/EFCore.PG/ValueGeneration/Internal/NpgsqlSequenceHiLoValueGenerator.cs +++ b/src/EFCore.PG/ValueGeneration/Internal/NpgsqlSequenceHiLoValueGenerator.cs @@ -60,7 +60,7 @@ protected override long GetNewLowValue() context: null, _commandLogger)), typeof(long), - CultureInfo.InvariantCulture); + CultureInfo.InvariantCulture)!; /// /// This API supports the Entity Framework Core infrastructure and is not intended to be used @@ -79,7 +79,7 @@ await _rawSqlCommandBuilder _commandLogger), cancellationToken), typeof(long), - CultureInfo.InvariantCulture); + CultureInfo.InvariantCulture)!; /// /// This API supports the Entity Framework Core infrastructure and is not intended to be used diff --git a/src/Shared/CodeAnnotations.cs b/src/Shared/CodeAnnotations.cs index b1e5907187..eaad9d8d2e 100644 --- a/src/Shared/CodeAnnotations.cs +++ b/src/Shared/CodeAnnotations.cs @@ -281,57 +281,6 @@ internal sealed class InvokerParameterNameAttribute : Attribute { } - /// - /// Indicates that the method is contained in a type that implements - /// System.ComponentModel.INotifyPropertyChanged interface and this method - /// is used to notify that some property value changed. - /// - /// - /// The method should be non-static and conform to one of the supported signatures: - /// - /// NotifyChanged(string) - /// NotifyChanged(params string[]) - /// NotifyChanged{T}(Expression{Func{T}}) - /// NotifyChanged{T,U}(Expression{Func{T,U}}) - /// SetProperty{T}(ref T, T, string) - /// - /// - /// - /// public class Foo : INotifyPropertyChanged { - /// public event PropertyChangedEventHandler PropertyChanged; - /// - /// [NotifyPropertyChangedInvocator] - /// protected virtual void NotifyChanged(string propertyName) { ... } - /// - /// string _name; - /// - /// public string Name { - /// get { return _name; } - /// set { _name = value; NotifyChanged("LastName"); /* Warning */ } - /// } - /// } - /// - /// Examples of generated notifications: - /// - /// NotifyChanged("Property") - /// NotifyChanged(() => Property) - /// NotifyChanged((VM x) => x.Property) - /// SetProperty(ref myField, value, "Property") - /// - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class NotifyPropertyChangedInvocatorAttribute : Attribute - { - public NotifyPropertyChangedInvocatorAttribute() { } - - public NotifyPropertyChangedInvocatorAttribute([NotNull] string parameterName) - { - ParameterName = parameterName; - } - - [CanBeNull] public string ParameterName { get; } - } - /// /// Describes dependency between method input and output. /// @@ -581,592 +530,6 @@ internal enum ImplicitUseTargetFlags WithMembers = Itself | Members } - /// - /// This attribute is intended to mark publicly available API - /// which should not be removed and so is treated as used. - /// - [MeansImplicitUse(ImplicitUseTargetFlags.WithMembers)] - [AttributeUsage(AttributeTargets.All, Inherited = false)] - internal sealed class PublicAPIAttribute : Attribute - { - public PublicAPIAttribute() { } - - public PublicAPIAttribute([NotNull] string comment) - { - Comment = comment; - } - - [CanBeNull] public string Comment { get; } - } - - /// - /// Tells code analysis engine if the parameter is completely handled when the invoked method is on stack. - /// If the parameter is a delegate, indicates that delegate is executed while the method is executed. - /// If the parameter is an enumerable, indicates that it is enumerated while the method is executed. - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class InstantHandleAttribute : Attribute - { - } - - /// - /// Indicates that a method does not make any observable state changes. - /// The same as System.Diagnostics.Contracts.PureAttribute. - /// - /// - /// [Pure] int Multiply(int x, int y) => x * y; - /// - /// void M() { - /// Multiply(123, 42); // Warning: Return value of pure method is not used - /// } - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class PureAttribute : Attribute - { - } - - /// - /// Indicates that the return value of the method invocation must be used. - /// - /// - /// Methods decorated with this attribute (in contrast to pure methods) might change state, - /// but make no sense without using their return value.
- /// Similarly to , this attribute - /// will help detecting usages of the method when the return value in not used. - /// Additionally, you can optionally specify a custom message, which will be used when showing warnings, e.g. - /// [MustUseReturnValue("Use the return value to...")]. - ///
- [AttributeUsage(AttributeTargets.Method)] - internal sealed class MustUseReturnValueAttribute : Attribute - { - public MustUseReturnValueAttribute() { } - - public MustUseReturnValueAttribute([NotNull] string justification) - { - Justification = justification; - } - - [CanBeNull] public string Justification { get; } - } - - /// - /// Indicates the type member or parameter of some type, that should be used instead of all other ways - /// to get the value of that type. This annotation is useful when you have some "context" value evaluated - /// and stored somewhere, meaning that all other ways to get this value must be consolidated with existing one. - /// - /// - /// class Foo { - /// [ProvidesContext] IBarService _barService = ...; - /// - /// void ProcessNode(INode node) { - /// DoSomething(node, node.GetGlobalServices().Bar); - /// // ^ Warning: use value of '_barService' field - /// } - /// } - /// - [AttributeUsage( - AttributeTargets.Field - | AttributeTargets.Property - | AttributeTargets.Parameter - | AttributeTargets.Method - | AttributeTargets.Class - | AttributeTargets.Interface - | AttributeTargets.Struct - | AttributeTargets.GenericParameter)] - internal sealed class ProvidesContextAttribute : Attribute - { - } - - /// - /// Indicates that a parameter is a path to a file or a folder within a web project. - /// Path can be relative or absolute, starting from web root (~). - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class PathReferenceAttribute : Attribute - { - public PathReferenceAttribute() { } - - public PathReferenceAttribute([NotNull, PathReference] string basePath) - { - BasePath = basePath; - } - - [CanBeNull] public string BasePath { get; } - } - - /// - /// An extension method marked with this attribute is processed by code completion - /// as a 'Source Template'. When the extension method is completed over some expression, its source code - /// is automatically expanded like a template at call site. - /// - /// - /// Template method body can contain valid source code and/or special comments starting with '$'. - /// Text inside these comments is added as source code when the template is applied. Template parameters - /// can be used either as additional method parameters or as identifiers wrapped in two '$' signs. - /// Use the attribute to specify macros for parameters. - /// - /// - /// In this example, the 'forEach' method is a source template available over all values - /// of enumerable types, producing ordinary C# 'foreach' statement and placing caret inside block: - /// - /// [SourceTemplate] - /// public static void forEach<T>(this IEnumerable<T> xs) { - /// foreach (var x in xs) { - /// //$ $END$ - /// } - /// } - /// - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class SourceTemplateAttribute : Attribute - { - } - - /// - /// Allows specifying a macro for a parameter of a source template. - /// - /// - /// You can apply the attribute on the whole method or on any of its additional parameters. The macro expression - /// is defined in the property. When applied on a method, the target - /// template parameter is defined in the property. To apply the macro silently - /// for the parameter, set the property value = -1. - /// - /// - /// Applying the attribute on a source template method: - /// - /// [SourceTemplate, Macro(Target = "item", Expression = "suggestVariableName()")] - /// public static void forEach<T>(this IEnumerable<T> collection) { - /// foreach (var item in collection) { - /// //$ $END$ - /// } - /// } - /// - /// Applying the attribute on a template method parameter: - /// - /// [SourceTemplate] - /// public static void something(this Entity x, [Macro(Expression = "guid()", Editable = -1)] string newguid) { - /// /*$ var $x$Id = "$newguid$" + x.ToString(); - /// x.DoSomething($x$Id); */ - /// } - /// - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method, AllowMultiple = true)] - internal sealed class MacroAttribute : Attribute - { - /// - /// Allows specifying a macro that will be executed for a source template - /// parameter when the template is expanded. - /// - [CanBeNull] public string Expression { get; set; } - - /// - /// Allows specifying which occurrence of the target parameter becomes editable when the template is deployed. - /// - /// - /// If the target parameter is used several times in the template, only one occurrence becomes editable; - /// other occurrences are changed synchronously. To specify the zero-based index of the editable occurrence, - /// use values >= 0. To make the parameter non-editable when the template is expanded, use -1. - /// - public int Editable { get; set; } - - /// - /// Identifies the target parameter of a source template if the - /// is applied on a template method. - /// - [CanBeNull] public string Target { get; set; } - } - - [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] - internal sealed class AspMvcAreaMasterLocationFormatAttribute : Attribute - { - public AspMvcAreaMasterLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] public string Format { get; } - } - - [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] - internal sealed class AspMvcAreaPartialViewLocationFormatAttribute : Attribute - { - public AspMvcAreaPartialViewLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] public string Format { get; } - } - - [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] - internal sealed class AspMvcAreaViewLocationFormatAttribute : Attribute - { - public AspMvcAreaViewLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] public string Format { get; } - } - - [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] - internal sealed class AspMvcMasterLocationFormatAttribute : Attribute - { - public AspMvcMasterLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] public string Format { get; } - } - - [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] - internal sealed class AspMvcPartialViewLocationFormatAttribute : Attribute - { - public AspMvcPartialViewLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] public string Format { get; } - } - - [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)] - internal sealed class AspMvcViewLocationFormatAttribute : Attribute - { - public AspMvcViewLocationFormatAttribute([NotNull] string format) - { - Format = format; - } - - [NotNull] public string Format { get; } - } - - /// - /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter - /// is an MVC action. If applied to a method, the MVC action name is calculated - /// implicitly from the context. Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class AspMvcActionAttribute : Attribute - { - public AspMvcActionAttribute() { } - - public AspMvcActionAttribute([NotNull] string anonymousProperty) - { - AnonymousProperty = anonymousProperty; - } - - [CanBeNull] public string AnonymousProperty { get; } - } - - /// - /// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC area. - /// Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class AspMvcAreaAttribute : Attribute - { - public AspMvcAreaAttribute() { } - - public AspMvcAreaAttribute([NotNull] string anonymousProperty) - { - AnonymousProperty = anonymousProperty; - } - - [CanBeNull] public string AnonymousProperty { get; } - } - - /// - /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is - /// an MVC controller. If applied to a method, the MVC controller name is calculated - /// implicitly from the context. Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String, String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class AspMvcControllerAttribute : Attribute - { - public AspMvcControllerAttribute() { } - - public AspMvcControllerAttribute([NotNull] string anonymousProperty) - { - AnonymousProperty = anonymousProperty; - } - - [CanBeNull] public string AnonymousProperty { get; } - } - - /// - /// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC Master. Use this attribute - /// for custom wrappers similar to System.Web.Mvc.Controller.View(String, String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class AspMvcMasterAttribute : Attribute - { - } - - /// - /// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC model type. Use this attribute - /// for custom wrappers similar to System.Web.Mvc.Controller.View(String, Object). - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class AspMvcModelTypeAttribute : Attribute - { - } - - /// - /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter is an MVC - /// partial view. If applied to a method, the MVC partial view name is calculated implicitly - /// from the context. Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(HtmlHelper, String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class AspMvcPartialViewAttribute : Attribute - { - } - - /// - /// ASP.NET MVC attribute. Allows disabling inspections for MVC views within a class or a method. - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] - internal sealed class AspMvcSuppressViewErrorAttribute : Attribute - { - } - - /// - /// ASP.NET MVC attribute. Indicates that a parameter is an MVC display template. - /// Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.DisplayExtensions.DisplayForModel(HtmlHelper, String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class AspMvcDisplayTemplateAttribute : Attribute - { - } - - /// - /// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC editor template. - /// Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Html.EditorExtensions.EditorForModel(HtmlHelper, String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class AspMvcEditorTemplateAttribute : Attribute - { - } - - /// - /// ASP.NET MVC attribute. Indicates that the marked parameter is an MVC template. - /// Use this attribute for custom wrappers similar to - /// System.ComponentModel.DataAnnotations.UIHintAttribute(System.String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class AspMvcTemplateAttribute : Attribute - { - } - - /// - /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter - /// is an MVC view component. If applied to a method, the MVC view name is calculated implicitly - /// from the context. Use this attribute for custom wrappers similar to - /// System.Web.Mvc.Controller.View(Object). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class AspMvcViewAttribute : Attribute - { - } - - /// - /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter - /// is an MVC view component name. - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class AspMvcViewComponentAttribute : Attribute - { - } - - /// - /// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter - /// is an MVC view component view. If applied to a method, the MVC view component view name is default. - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class AspMvcViewComponentViewAttribute : Attribute - { - } - - /// - /// ASP.NET MVC attribute. When applied to a parameter of an attribute, - /// indicates that this parameter is an MVC action name. - /// - /// - /// [ActionName("Foo")] - /// public ActionResult Login(string returnUrl) { - /// ViewBag.ReturnUrl = Url.Action("Foo"); // OK - /// return RedirectToAction("Bar"); // Error: Cannot resolve action - /// } - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)] - internal sealed class AspMvcActionSelectorAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field)] - internal sealed class HtmlElementAttributesAttribute : Attribute - { - public HtmlElementAttributesAttribute() { } - - public HtmlElementAttributesAttribute([NotNull] string name) - { - Name = name; - } - - [CanBeNull] public string Name { get; } - } - - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)] - internal sealed class HtmlAttributeValueAttribute : Attribute - { - public HtmlAttributeValueAttribute([NotNull] string name) - { - Name = name; - } - - [NotNull] public string Name { get; } - } - - /// - /// Razor attribute. Indicates that the marked parameter or method is a Razor section. - /// Use this attribute for custom wrappers similar to - /// System.Web.WebPages.WebPageBase.RenderSection(String). - /// - [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)] - internal sealed class RazorSectionAttribute : Attribute - { - } - - /// - /// Indicates how method, constructor invocation, or property access - /// over collection type affects the contents of the collection. - /// Use to specify the access type. - /// - /// - /// Using this attribute only makes sense if all collection methods are marked with this attribute. - /// - /// - /// public class MyStringCollection : List<string> - /// { - /// [CollectionAccess(CollectionAccessType.Read)] - /// public string GetFirstString() - /// { - /// return this.ElementAt(0); - /// } - /// } - /// class Test - /// { - /// public void Foo() - /// { - /// // Warning: Contents of the collection is never updated - /// var col = new MyStringCollection(); - /// string x = col.GetFirstString(); - /// } - /// } - /// - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property)] - internal sealed class CollectionAccessAttribute : Attribute - { - public CollectionAccessAttribute(CollectionAccessType collectionAccessType) - { - CollectionAccessType = collectionAccessType; - } - - public CollectionAccessType CollectionAccessType { get; } - } - - /// - /// Provides a value for the to define - /// how the collection method invocation affects the contents of the collection. - /// - [Flags] - internal enum CollectionAccessType - { - /// Method does not use or modify content of the collection. - None = 0, - - /// Method only reads content of the collection but does not modify it. - Read = 1, - - /// Method can change content of the collection but does not add new elements. - ModifyExistingContent = 2, - - /// Method can add new elements to the collection. - UpdatedContent = ModifyExistingContent | 4 - } - - /// - /// Indicates that the marked method is assertion method, i.e. it halts the control flow if - /// one of the conditions is satisfied. To set the condition, mark one of the parameters with - /// attribute. - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class AssertionMethodAttribute : Attribute - { - } - - /// - /// Indicates the condition parameter of the assertion method. The method itself should be - /// marked by attribute. The mandatory argument of - /// the attribute is the assertion type. - /// - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class AssertionConditionAttribute : Attribute - { - public AssertionConditionAttribute(AssertionConditionType conditionType) - { - ConditionType = conditionType; - } - - public AssertionConditionType ConditionType { get; } - } - - /// - /// Specifies assertion type. If the assertion method argument satisfies the condition, - /// then the execution continues. Otherwise, execution is assumed to be halted. - /// - internal enum AssertionConditionType - { - /// Marked parameter should be evaluated to true. - IS_TRUE = 0, - - /// Marked parameter should be evaluated to false. - IS_FALSE = 1, - - /// Marked parameter should be evaluated to null value. - IS_NULL = 2, - - /// Marked parameter should be evaluated to not null value. - IS_NOT_NULL = 3, - } - - /// - /// Indicates that the marked method unconditionally terminates control flow execution. - /// For example, it could unconditionally throw exception. - /// - [Obsolete("Use [ContractAnnotation('=> halt')] instead")] - [AttributeUsage(AttributeTargets.Method)] - internal sealed class TerminatesProgramAttribute : Attribute - { - } - - /// - /// Indicates that method is pure LINQ method, with postponed enumeration (like Enumerable.Select, - /// .Where). This annotation allows inference of [InstantHandle] annotation for parameters - /// of delegate type by analyzing LINQ method chains. - /// - [AttributeUsage(AttributeTargets.Method)] - internal sealed class LinqTunnelAttribute : Attribute - { - } - /// /// Indicates that IEnumerable passed as a parameter is not enumerated. /// Use this annotation to suppress the 'Possible multiple enumeration of IEnumerable' inspection. @@ -1195,183 +558,4 @@ internal sealed class NoEnumerationAttribute : Attribute internal sealed class RegexPatternAttribute : Attribute { } - - /// - /// Prevents the Member Reordering feature from tossing members of the marked class. - /// - /// - /// The attribute must be mentioned in your member reordering patterns. - /// - [AttributeUsage( - AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Enum)] - internal sealed class NoReorderAttribute : Attribute - { - } - - /// - /// XAML attribute. Indicates the type that has ItemsSource property and should be treated - /// as ItemsControl-derived type, to enable inner items DataContext type resolve. - /// - [AttributeUsage(AttributeTargets.Class)] - internal sealed class XamlItemsControlAttribute : Attribute - { - } - - /// - /// XAML attribute. Indicates the property of some BindingBase-derived type, that - /// is used to bind some item of ItemsControl-derived type. This annotation will - /// enable the DataContext type resolve for XAML bindings for such properties. - /// - /// - /// Property should have the tree ancestor of the ItemsControl type or - /// marked with the attribute. - /// - [AttributeUsage(AttributeTargets.Property)] - internal sealed class XamlItemBindingOfItemsControlAttribute : Attribute - { - } - - /// - /// XAML attribute. Indicates the property of some Style-derived type, that - /// is used to style items of ItemsControl-derived type. This annotation will - /// enable the DataContext type resolve for XAML bindings for such properties. - /// - /// - /// Property should have the tree ancestor of the ItemsControl type or - /// marked with the attribute. - /// - [AttributeUsage(AttributeTargets.Property)] - internal sealed class XamlItemStyleOfItemsControlAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - internal sealed class AspChildControlTypeAttribute : Attribute - { - public AspChildControlTypeAttribute([NotNull] string tagName, [NotNull] Type controlType) - { - TagName = tagName; - ControlType = controlType; - } - - [NotNull] public string TagName { get; } - - [NotNull] public Type ControlType { get; } - } - - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] - internal sealed class AspDataFieldAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] - internal sealed class AspDataFieldsAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Property)] - internal sealed class AspMethodPropertyAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - internal sealed class AspRequiredAttributeAttribute : Attribute - { - public AspRequiredAttributeAttribute([NotNull] string attribute) - { - Attribute = attribute; - } - - [NotNull] public string Attribute { get; } - } - - [AttributeUsage(AttributeTargets.Property)] - internal sealed class AspTypePropertyAttribute : Attribute - { - public bool CreateConstructorReferences { get; } - - public AspTypePropertyAttribute(bool createConstructorReferences) - { - CreateConstructorReferences = createConstructorReferences; - } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class RazorImportNamespaceAttribute : Attribute - { - public RazorImportNamespaceAttribute([NotNull] string name) - { - Name = name; - } - - [NotNull] public string Name { get; } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class RazorInjectionAttribute : Attribute - { - public RazorInjectionAttribute([NotNull] string type, [NotNull] string fieldName) - { - Type = type; - FieldName = fieldName; - } - - [NotNull] public string Type { get; } - - [NotNull] public string FieldName { get; } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class RazorDirectiveAttribute : Attribute - { - public RazorDirectiveAttribute([NotNull] string directive) - { - Directive = directive; - } - - [NotNull] public string Directive { get; } - } - - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - internal sealed class RazorPageBaseTypeAttribute : Attribute - { - public RazorPageBaseTypeAttribute([NotNull] string baseType) - { - BaseType = baseType; - } - - public RazorPageBaseTypeAttribute([NotNull] string baseType, string pageName) - { - BaseType = baseType; - PageName = pageName; - } - - [NotNull] public string BaseType { get; } - [CanBeNull] public string PageName { get; } - } - - [AttributeUsage(AttributeTargets.Method)] - internal sealed class RazorHelperCommonAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Property)] - internal sealed class RazorLayoutAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Method)] - internal sealed class RazorWriteLiteralMethodAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Method)] - internal sealed class RazorWriteMethodAttribute : Attribute - { - } - - [AttributeUsage(AttributeTargets.Parameter)] - internal sealed class RazorWriteMethodParameterAttribute : Attribute - { - } } diff --git a/src/Shared/SharedTypeExtensions.cs b/src/Shared/SharedTypeExtensions.cs index fa6365d673..f2911567e1 100644 --- a/src/Shared/SharedTypeExtensions.cs +++ b/src/Shared/SharedTypeExtensions.cs @@ -4,8 +4,13 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; +using System.Text; +using JetBrains.Annotations; + +#nullable enable // ReSharper disable once CheckNamespace namespace System @@ -13,7 +18,28 @@ namespace System [DebuggerStepThrough] internal static class SharedTypeExtensions { - public static Type UnwrapNullableType(this Type type) => Nullable.GetUnderlyingType(type) ?? type; + private static readonly Dictionary _builtInTypeNames = new() + { + { typeof(bool), "bool" }, + { typeof(byte), "byte" }, + { typeof(char), "char" }, + { typeof(decimal), "decimal" }, + { typeof(double), "double" }, + { typeof(float), "float" }, + { typeof(int), "int" }, + { typeof(long), "long" }, + { typeof(object), "object" }, + { typeof(sbyte), "sbyte" }, + { typeof(short), "short" }, + { typeof(string), "string" }, + { typeof(uint), "uint" }, + { typeof(ulong), "ulong" }, + { typeof(ushort), "ushort" }, + { typeof(void), "void" } + }; + + public static Type UnwrapNullableType(this Type type) + => Nullable.GetUnderlyingType(type) ?? type; public static bool IsNullableValueType(this Type type) => type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); @@ -24,6 +50,19 @@ public static bool IsNullableType(this Type type) public static bool IsValidEntityType(this Type type) => type.IsClass; + public static bool IsPropertyBagType(this Type type) + { + if (type.IsGenericTypeDefinition) + { + return false; + } + + var types = GetGenericTypeImplementations(type, typeof(IDictionary<,>)); + return types.Any( + t => t.GetGenericArguments()[0] == typeof(string) + && t.GetGenericArguments()[1] == typeof(object)); + } + public static Type MakeNullable(this Type type, bool nullable = true) => type.IsNullableType() == nullable ? type @@ -94,7 +133,7 @@ public static bool IsTupleType(this Type type) return false; } - public static PropertyInfo GetAnyProperty(this Type type, string name) + public static PropertyInfo? GetAnyProperty(this Type type, string name) { var props = type.GetRuntimeProperties().Where(p => p.Name == name).ToList(); if (props.Count > 1) @@ -105,6 +144,90 @@ public static PropertyInfo GetAnyProperty(this Type type, string name) return props.SingleOrDefault(); } + public static MethodInfo GetRequiredMethod(this Type type, string name, params Type[] parameters) + { + var method = type.GetTypeInfo().GetMethod(name, parameters); + + if (method == null + && parameters.Length == 0) + { + method = type.GetMethod(name); + } + + if (method == null) + { + throw new InvalidOperationException(); + } + + return method; + } + + public static PropertyInfo GetRequiredProperty(this Type type, string name) + { + var property = type.GetTypeInfo().GetProperty(name); + if (property == null) + { + throw new InvalidOperationException(); + } + + return property; + } + + public static FieldInfo GetRequiredDeclaredField(this Type type, string name) + { + var field = type.GetTypeInfo().GetDeclaredField(name); + if (field == null) + { + throw new InvalidOperationException(); + } + + return field; + } + + public static MethodInfo GetRequiredDeclaredMethod(this Type type, string name) + { + var method = type.GetTypeInfo().GetDeclaredMethod(name); + if (method == null) + { + throw new InvalidOperationException(); + } + + return method; + } + + public static PropertyInfo GetRequiredDeclaredProperty(this Type type, string name) + { + var property = type.GetTypeInfo().GetDeclaredProperty(name); + if (property == null) + { + throw new InvalidOperationException(); + } + + return property; + } + + public static MethodInfo GetRequiredRuntimeMethod(this Type type, string name, params Type[] parameters) + { + var method = type.GetTypeInfo().GetRuntimeMethod(name, parameters); + if (method == null) + { + throw new InvalidOperationException(); + } + + return method; + } + + public static PropertyInfo GetRequiredRuntimeProperty(this Type type, string name) + { + var property = type.GetTypeInfo().GetRuntimeProperty(name); + if (property == null) + { + throw new InvalidOperationException(); + } + + return property; + } + public static bool IsInstantiable(this Type type) => !type.IsAbstract && !type.IsInterface @@ -135,11 +258,11 @@ public static Type GetSequenceType(this Type type) return sequenceType; } - public static Type TryGetSequenceType(this Type type) + public static Type? TryGetSequenceType(this Type type) => type.TryGetElementType(typeof(IEnumerable<>)) ?? type.TryGetElementType(typeof(IAsyncEnumerable<>)); - public static Type TryGetElementType(this Type type, Type interfaceOrBaseType) + public static Type? TryGetElementType(this Type type, Type interfaceOrBaseType) { if (type.IsGenericTypeDefinition) { @@ -148,7 +271,7 @@ public static Type TryGetElementType(this Type type, Type interfaceOrBaseType) var types = GetGenericTypeImplementations(type, interfaceOrBaseType); - Type singleImplementation = null; + Type? singleImplementation = null; foreach (var implementation in types) { if (singleImplementation == null) @@ -165,6 +288,8 @@ public static Type TryGetElementType(this Type type, Type interfaceOrBaseType) return singleImplementation?.GenericTypeArguments.FirstOrDefault(); } +#nullable disable + public static bool IsCompatibleWith(this Type propertyType, Type fieldType) { if (propertyType.IsAssignableFrom(fieldType) @@ -344,5 +469,135 @@ public static bool IsQueryableType(this Type type) return type.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IQueryable<>)); } + + /// + /// 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 static string DisplayName([NotNull] this Type type, bool fullName = true) + { + var stringBuilder = new StringBuilder(); + ProcessType(stringBuilder, type, fullName); + return stringBuilder.ToString(); + } + + private static void ProcessType(StringBuilder builder, Type type, bool fullName) + { + if (type.IsGenericType) + { + var genericArguments = type.GetGenericArguments(); + ProcessGenericType(builder, type, genericArguments, genericArguments.Length, fullName); + } + else if (type.IsArray) + { + ProcessArrayType(builder, type, fullName); + } + else if (_builtInTypeNames.TryGetValue(type, out var builtInName)) + { + builder.Append(builtInName); + } + else if (!type.IsGenericParameter) + { + builder.Append(fullName ? type.FullName : type.Name); + } + } + + private static void ProcessArrayType(StringBuilder builder, Type type, bool fullName) + { + var innerType = type; + while (innerType.IsArray) + { + innerType = innerType.GetElementType(); + } + + ProcessType(builder, innerType, fullName); + + while (type.IsArray) + { + builder.Append('['); + builder.Append(',', type.GetArrayRank() - 1); + builder.Append(']'); + type = type.GetElementType(); + } + } + + private static void ProcessGenericType(StringBuilder builder, Type type, Type[] genericArguments, int length, bool fullName) + { + var offset = type.IsNested ? type.DeclaringType.GetGenericArguments().Length : 0; + + if (fullName) + { + if (type.IsNested) + { + ProcessGenericType(builder, type.DeclaringType, genericArguments, offset, fullName); + builder.Append('+'); + } + else + { + builder.Append(type.Namespace); + builder.Append('.'); + } + } + + var genericPartIndex = type.Name.IndexOf('`'); + if (genericPartIndex <= 0) + { + builder.Append(type.Name); + return; + } + + builder.Append(type.Name, 0, genericPartIndex); + builder.Append('<'); + + for (var i = offset; i < length; i++) + { + ProcessType(builder, genericArguments[i], fullName); + if (i + 1 == length) + { + continue; + } + + builder.Append(','); + if (!genericArguments[i + 1].IsGenericParameter) + { + builder.Append(' '); + } + } + + builder.Append('>'); + } + + public static IEnumerable GetNamespaces([NotNull] this Type type) + { + if (_builtInTypeNames.ContainsKey(type)) + { + yield break; + } + + yield return type.Namespace; + + if (type.IsGenericType) + { + foreach (var typeArgument in type.GenericTypeArguments) + { + foreach (var ns in typeArgument.GetNamespaces()) + { + yield return ns; + } + } + } + } + + public static ConstantExpression GetDefaultValueConstant(this Type type) + => (ConstantExpression)_generateDefaultValueConstantMethod + .MakeGenericMethod(type).Invoke(null, Array.Empty()); + + private static readonly MethodInfo _generateDefaultValueConstantMethod = + typeof(SharedTypeExtensions).GetTypeInfo().GetDeclaredMethod(nameof(GenerateDefaultValueConstant)); + + private static ConstantExpression GenerateDefaultValueConstant() + => Expression.Constant(default(TDefault), typeof(TDefault)); } } diff --git a/test/EFCore.PG.NodaTime.FunctionalTests/NpgsqlNodaTimeTypeMappingTest.cs b/test/EFCore.PG.NodaTime.FunctionalTests/NpgsqlNodaTimeTypeMappingTest.cs index 07a8fbf110..711405969b 100644 --- a/test/EFCore.PG.NodaTime.FunctionalTests/NpgsqlNodaTimeTypeMappingTest.cs +++ b/test/EFCore.PG.NodaTime.FunctionalTests/NpgsqlNodaTimeTypeMappingTest.cs @@ -184,6 +184,8 @@ public void GenerateCodeLiteral_returns_period_literal() "NodaTime.Period.FromSeconds(7L) + NodaTime.Period.FromMilliseconds(8L) + NodaTime.Period.FromNanoseconds(9L)", CodeLiteral(Period.FromYears(1) + Period.FromMonths(2) + Period.FromWeeks(3) + Period.FromDays(4) + Period.FromHours(5) + Period.FromMinutes(6) + Period.FromSeconds(7) + Period.FromMilliseconds(8) + Period.FromNanoseconds(9))); + + Assert.Equal("NodaTime.Period.Zero", CodeLiteral(Period.Zero)); } [Fact] @@ -195,6 +197,8 @@ public void GenerateCodeLiteral_returns_duration_literal() "NodaTime.Duration.FromSeconds(7L) + NodaTime.Duration.FromMilliseconds(8L)", CodeLiteral(Duration.FromDays(4) + Duration.FromHours(5) + Duration.FromMinutes(6) + Duration.FromSeconds(7) + Duration.FromMilliseconds(8))); + + Assert.Equal("NodaTime.Duration.Zero", CodeLiteral(Duration.Zero)); } #region Support