Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Annotate Storage for nullability #23423

Merged
merged 2 commits into from
Jan 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/EFCore.Abstractions/CommentAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
namespace Microsoft.EntityFrameworkCore
{
/// <summary>
/// Marks a class, property or field with a comment which will be included in the SQL sent to the database .
/// Marks a class, property or field with a comment to be set on the corresponding database table or column.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field)]
public sealed class CommentAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="CommentAttribute" /> class.
/// </summary>
/// <param name="comment">The comment.</param>
/// <param name="comment"> The comment. </param>
public CommentAttribute([NotNull] string comment)
{
Check.NotEmpty(comment, nameof(comment));
Expand All @@ -25,7 +25,7 @@ public CommentAttribute([NotNull] string comment)
}

/// <summary>
/// The Comment
/// The comment to be configured.
/// </summary>
public string Comment { get; }
}
Expand Down
1 change: 0 additions & 1 deletion src/EFCore.Cosmos/Query/Internal/SqlExpressionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ when sqlUnaryExpression.IsLogicalNot():
throw new InvalidOperationException(
CosmosStrings.UnsupportedOperatorForSqlExpression(
sqlUnaryExpression.OperatorType, typeof(SqlUnaryExpression).ShortDisplayName()));
;
}

return new SqlUnaryExpression(sqlUnaryExpression.OperatorType, operand, resultType, resultTypeMapping);
Expand Down
90 changes: 45 additions & 45 deletions src/EFCore.Cosmos/Storage/Internal/CosmosExecutionStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using Microsoft.Azure.Cosmos;
using Microsoft.EntityFrameworkCore.Storage;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Cosmos.Storage.Internal
{
/// <summary>
Expand Down Expand Up @@ -97,24 +99,15 @@ public CosmosExecutionStrategy([NotNull] ExecutionStrategyDependencies dependenc
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override bool ShouldRetryOn(Exception exception)
protected override bool ShouldRetryOn(Exception? exception)
{
if (exception is CosmosException cosmosException)
return exception switch
{
return IsTransient(cosmosException.StatusCode);
}

if (exception is HttpException httpException)
{
return IsTransient(httpException.Response.StatusCode);
}

if (exception is WebException webException)
{
return IsTransient(((HttpWebResponse)webException.Response).StatusCode);
}

return false;
CosmosException cosmosException => IsTransient(cosmosException.StatusCode),
HttpException httpException => IsTransient(httpException.Response.StatusCode),
WebException webException => IsTransient(((HttpWebResponse)webException.Response!).StatusCode),
_ => false
};

static bool IsTransient(HttpStatusCode statusCode)
=> statusCode == HttpStatusCode.ServiceUnavailable
Expand All @@ -136,47 +129,54 @@ static bool IsTransient(HttpStatusCode statusCode)
?? baseDelay;
}

private static TimeSpan? GetDelayFromException(Exception exception)
private static TimeSpan? GetDelayFromException(Exception? exception)
{
if (exception is CosmosException cosmosException)
switch (exception)
{
return cosmosException.RetryAfter;
}
case CosmosException cosmosException:
return cosmosException.RetryAfter;

if (exception is HttpException httpException)
{
if (httpException.Response.Headers.TryGetValues("x-ms-retry-after-ms", out var values)
&& TryParseMsRetryAfter(values.FirstOrDefault(), out var delay))
case HttpException httpException:
{
return delay;
if (httpException.Response.Headers.TryGetValues("x-ms-retry-after-ms", out var values)
&& TryParseMsRetryAfter(values.FirstOrDefault(), out var delay))
{
return delay;
}

if (httpException.Response.Headers.TryGetValues("Retry-After", out values)
&& TryParseRetryAfter(values.FirstOrDefault(), out delay))
{
return delay;
}

return null;
}

if (httpException.Response.Headers.TryGetValues("Retry-After", out values)
&& TryParseRetryAfter(values.FirstOrDefault(), out delay))
case WebException webException:
{
return delay;
}
}
var response = (HttpWebResponse)webException.Response!;

if (exception is WebException webException)
{
var response = (HttpWebResponse)webException.Response;
var delayString = response.Headers.GetValues("x-ms-retry-after-ms")?.FirstOrDefault();
if (TryParseMsRetryAfter(delayString, out var delay))
{
return delay;
}

var delayString = response.Headers.GetValues("x-ms-retry-after-ms")?.FirstOrDefault();
if (TryParseMsRetryAfter(delayString, out var delay))
{
return delay;
}
delayString = response.Headers.GetValues("Retry-After")?.FirstOrDefault();
if (TryParseRetryAfter(delayString, out delay))
{
return delay;
}

delayString = response.Headers.GetValues("Retry-After")?.FirstOrDefault();
if (TryParseRetryAfter(delayString, out delay))
{
return delay;
return null;
}

default:
return null;
}

return null;
static bool TryParseMsRetryAfter(string delayString, out TimeSpan delay)
static bool TryParseMsRetryAfter(string? delayString, out TimeSpan delay)
{
delay = default;
if (delayString == null)
Expand All @@ -193,7 +193,7 @@ static bool TryParseMsRetryAfter(string delayString, out TimeSpan delay)
return false;
}

static bool TryParseRetryAfter(string delayString, out TimeSpan delay)
static bool TryParseRetryAfter(string? delayString, out TimeSpan delay)
{
delay = default;
if (delayString == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public CosmosExecutionStrategyFactory([NotNull] ExecutionStrategyDependencies de

Dependencies = dependencies;

_createExecutionStrategy = dependencies.Options?.FindExtension<CosmosOptionsExtension>()?.ExecutionStrategyFactory
_createExecutionStrategy = dependencies.Options.FindExtension<CosmosOptionsExtension>()?.ExecutionStrategyFactory
?? CreateDefaultStrategy;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Microsoft.EntityFrameworkCore.Storage.Internal;
using Microsoft.Extensions.DependencyInjection;

#nullable enable

namespace Microsoft.EntityFrameworkCore.Design.Internal
{
/// <summary>
Expand All @@ -24,15 +26,15 @@ namespace Microsoft.EntityFrameworkCore.Design.Internal
/// </summary>
public class DesignTimeConnectionStringResolver : NamedConnectionStringResolverBase
{
private readonly Func<IServiceProvider> _applicationServiceProviderAccessor;
private readonly Func<IServiceProvider>? _applicationServiceProviderAccessor;

/// <summary>
/// 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.
/// </summary>
public DesignTimeConnectionStringResolver([CanBeNull] Func<IServiceProvider> applicationServiceProviderAccessor)
public DesignTimeConnectionStringResolver([CanBeNull] Func<IServiceProvider>? applicationServiceProviderAccessor)
{
_applicationServiceProviderAccessor = applicationServiceProviderAccessor;
}
Expand All @@ -43,7 +45,7 @@ public DesignTimeConnectionStringResolver([CanBeNull] Func<IServiceProvider> app
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override IServiceProvider ApplicationServiceProvider
protected override IServiceProvider? ApplicationServiceProvider
=> _applicationServiceProviderAccessor?.Invoke();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
using Microsoft.EntityFrameworkCore.Utilities;
using Microsoft.Extensions.DependencyInjection;

#nullable enable

// ReSharper disable once CheckNamespace
namespace Microsoft.EntityFrameworkCore
{
Expand Down Expand Up @@ -177,7 +179,7 @@ public static int ExecuteSqlRaw(
public static int ExecuteSqlInterpolated(
[NotNull] this DatabaseFacade databaseFacade,
[NotNull] FormattableString sql)
=> ExecuteSqlRaw(databaseFacade, sql.Format, sql.GetArguments());
=> ExecuteSqlRaw(databaseFacade, sql.Format, sql.GetArguments()!);

/// <summary>
/// <para>
Expand Down Expand Up @@ -274,7 +276,7 @@ public static Task<int> ExecuteSqlInterpolatedAsync(
[NotNull] this DatabaseFacade databaseFacade,
[NotNull] FormattableString sql,
CancellationToken cancellationToken = default)
=> ExecuteSqlRawAsync(databaseFacade, sql.Format, sql.GetArguments(), cancellationToken);
=> ExecuteSqlRawAsync(databaseFacade, sql.Format, sql.GetArguments()!, cancellationToken);

/// <summary>
/// <para>
Expand Down Expand Up @@ -442,15 +444,15 @@ public static DbConnection GetDbConnection([NotNull] this DatabaseFacade databas
/// </summary>
/// <param name="databaseFacade"> The <see cref="DatabaseFacade" /> for the context. </param>
/// <param name="connection"> The connection. </param>
public static void SetDbConnection([NotNull] this DatabaseFacade databaseFacade, [CanBeNull] DbConnection connection)
public static void SetDbConnection([NotNull] this DatabaseFacade databaseFacade, [CanBeNull] DbConnection? connection)
=> GetFacadeDependencies(databaseFacade).RelationalConnection.DbConnection = connection;

/// <summary>
/// Gets the underlying connection string configured for this <see cref="DbContext" />.
/// </summary>
/// <param name="databaseFacade"> The <see cref="DatabaseFacade" /> for the context. </param>
/// <returns> The connection string. </returns>
public static string GetConnectionString([NotNull] this DatabaseFacade databaseFacade)
public static string? GetConnectionString([NotNull] this DatabaseFacade databaseFacade)
=> GetFacadeDependencies(databaseFacade).RelationalConnection.ConnectionString;

/// <summary>
Expand All @@ -463,7 +465,7 @@ public static string GetConnectionString([NotNull] this DatabaseFacade databaseF
/// </summary>
/// <param name="databaseFacade"> The <see cref="DatabaseFacade" /> for the context. </param>
/// <param name="connectionString"> The connection string. </param>
public static void SetConnectionString([NotNull] this DatabaseFacade databaseFacade, [CanBeNull] string connectionString)
public static void SetConnectionString([NotNull] this DatabaseFacade databaseFacade, [CanBeNull] string? connectionString)
=> GetFacadeDependencies(databaseFacade).RelationalConnection.ConnectionString = connectionString;

/// <summary>
Expand Down Expand Up @@ -552,9 +554,9 @@ public static Task<IDbContextTransaction> BeginTransactionAsync(
/// <param name="databaseFacade"> The <see cref="DatabaseFacade" /> for the context. </param>
/// <param name="transaction"> The <see cref="DbTransaction" /> to use. </param>
/// <returns> A <see cref="IDbContextTransaction" /> that encapsulates the given transaction. </returns>
public static IDbContextTransaction UseTransaction(
public static IDbContextTransaction? UseTransaction(
[NotNull] this DatabaseFacade databaseFacade,
[CanBeNull] DbTransaction transaction)
[CanBeNull] DbTransaction? transaction)
=> databaseFacade.UseTransaction(transaction, Guid.NewGuid());

/// <summary>
Expand All @@ -564,9 +566,9 @@ public static IDbContextTransaction UseTransaction(
/// <param name="transaction"> The <see cref="DbTransaction" /> to use. </param>
/// <param name="transactionId"> The unique identifier for the transaction. </param>
/// <returns> A <see cref="IDbContextTransaction" /> that encapsulates the given transaction. </returns>
public static IDbContextTransaction UseTransaction(
public static IDbContextTransaction? UseTransaction(
[NotNull] this DatabaseFacade databaseFacade,
[CanBeNull] DbTransaction transaction,
[CanBeNull] DbTransaction? transaction,
Guid transactionId)
{
var transactionManager = GetTransactionManager(databaseFacade);
Expand All @@ -587,9 +589,9 @@ public static IDbContextTransaction UseTransaction(
/// <param name="cancellationToken"> A <see cref="CancellationToken" /> to observe while waiting for the task to complete. </param>
/// <returns> A <see cref="Task" /> containing the <see cref="IDbContextTransaction" /> for the given transaction. </returns>
/// <exception cref="OperationCanceledException"> If the <see cref="CancellationToken"/> is canceled. </exception>
public static Task<IDbContextTransaction> UseTransactionAsync(
public static Task<IDbContextTransaction?> UseTransactionAsync(
[NotNull] this DatabaseFacade databaseFacade,
[CanBeNull] DbTransaction transaction,
[CanBeNull] DbTransaction? transaction,
CancellationToken cancellationToken = default)
=> databaseFacade.UseTransactionAsync(transaction, Guid.NewGuid(), cancellationToken);

Expand All @@ -602,9 +604,9 @@ public static Task<IDbContextTransaction> UseTransactionAsync(
/// <param name="cancellationToken"> A <see cref="CancellationToken" /> to observe while waiting for the task to complete. </param>
/// <returns> A <see cref="Task" /> containing the <see cref="IDbContextTransaction" /> for the given transaction. </returns>
/// <exception cref="OperationCanceledException"> If the <see cref="CancellationToken"/> is canceled. </exception>
public static Task<IDbContextTransaction> UseTransactionAsync(
public static Task<IDbContextTransaction?> UseTransactionAsync(
[NotNull] this DatabaseFacade databaseFacade,
[CanBeNull] DbTransaction transaction,
[CanBeNull] DbTransaction? transaction,
Guid transactionId,
CancellationToken cancellationToken = default)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
Expand Down Expand Up @@ -44,9 +45,7 @@ public static bool AreCompatible(
var columnNames = foreignKey.Properties.GetColumnNames(storeObject);
var duplicateColumnNames = duplicateForeignKey.Properties.GetColumnNames(storeObject);
if (columnNames is null
|| duplicateColumnNames is null
|| principalTable is null
|| duplicatePrincipalTable is null)
|| duplicateColumnNames is null)
{
if (shouldThrow)
{
Expand All @@ -66,11 +65,13 @@ public static bool AreCompatible(
return false;
}

var principalColumns = foreignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value);
var duplicatePrincipalColumns = duplicateForeignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value);
if (principalTable != duplicatePrincipalTable
|| principalColumns == null
|| duplicatePrincipalColumns == null)
if (principalTable is null
|| duplicatePrincipalTable is null
|| principalTable != duplicatePrincipalTable
|| !(foreignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value)
is IReadOnlyList<string> principalColumns)
|| !(duplicateForeignKey.PrincipalKey.Properties.GetColumnNames(principalTable.Value)
is IReadOnlyList<string> duplicatePrincipalColumns))
{
if (shouldThrow)
{
Expand All @@ -81,7 +82,9 @@ public static bool AreCompatible(
duplicateForeignKey.Properties.Format(),
duplicateForeignKey.DeclaringEntityType.DisplayName(),
foreignKey.DeclaringEntityType.GetSchemaQualifiedTableName(),
foreignKey.GetConstraintName(storeObject, principalTable.Value),
principalTable.HasValue
? foreignKey.GetConstraintName(storeObject, principalTable.Value)
: foreignKey.GetDefaultName(),
principalType.GetSchemaQualifiedTableName(),
duplicatePrincipalType.GetSchemaQualifiedTableName()));
}
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore.Relational/Query/ISqlExpressionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public interface ISqlExpressionFactory
/// <param name="type"> The CLR type. </param>
/// <returns> The type mapping, or <see langword="null" /> if none was found. </returns>
[Obsolete("Use IRelationalTypeMappingSource directly.")]
RelationalTypeMapping FindMapping([NotNull] Type type);
RelationalTypeMapping? FindMapping([NotNull] Type type);

/// <summary>
/// Applies type mapping to the given <see cref="SqlExpression" />.
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore.Relational/Query/Internal/BufferedDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1270,7 +1270,7 @@ private void InitializeFields()
for (var i = 0; i < _columns.Count; i++)
{
var column = _columns[i];
if (!readerColumns.TryGetValue(column.Name, out var ordinal))
if (!readerColumns.TryGetValue(column.Name!, out var ordinal))
{
throw new InvalidOperationException(RelationalStrings.FromSqlMissingColumn(column.Name));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public virtual SelectExpression Expand(
}

updatedFromSql = fromSql.Update(
Expression.Constant(new CompositeRelationalParameter(parameterExpression.Name, subParameters)));
Expression.Constant(new CompositeRelationalParameter(parameterExpression.Name!, subParameters)));

_visitedFromSqlExpressions[fromSql] = updatedFromSql;
break;
Expand Down
Loading