Skip to content

Commit

Permalink
Merge branch 'release/7.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
ajcvickers committed Sep 16, 2022
2 parents 53db832 + d28a1c7 commit 767bc93
Show file tree
Hide file tree
Showing 42 changed files with 5,603 additions and 1,629 deletions.
6 changes: 3 additions & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ stages:
enablePublishTestResults: true
pool:
${{ if or(ne(variables['System.TeamProject'], 'internal'), in(variables['Build.Reason'], 'Manual', 'PullRequest', 'Schedule')) }}:
vmImage: ubuntu-18.04
vmImage: ubuntu-22.04
${{ if and(eq(variables['System.TeamProject'], 'internal'), notin(variables['Build.Reason'], 'Manual', 'PullRequest', 'Schedule')) }}:
name: NetCore1ESPool-Svc-Internal
demands: ImageOverride -equals Build.Ubuntu.1804.Amd64
Expand Down Expand Up @@ -210,12 +210,12 @@ stages:
value: $(_BuildConfig)
- ${{ if eq(variables['System.TeamProject'], 'public') }}:
- name: HelixTargetQueues
value: OSX.1100.Amd64.Open;(Ubuntu.1804.Amd64.SqlServer)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-sqlserver-amd64-20220131172221-d5c5072
value: OSX.1100.Amd64.Open;(Ubuntu.2204.Amd64.SqlServer)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-sqlserver-amd64-20220131172221-d5c5072
- name: _HelixAccessToken
value: '' # Needed for public queues
- ${{ if ne(variables['System.TeamProject'], 'public') }}:
- name: HelixTargetQueues
value: OSX.1100.Amd64;(Ubuntu.1804.Amd64.SqlServer)Ubuntu.1804.Amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-sqlserver-amd64-20220131172221-d5c5072
value: OSX.1100.Amd64;(Ubuntu.2204.Amd64.SqlServer)Ubuntu.2204.Amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-sqlserver-amd64-20220131172221-d5c5072
- name: _HelixAccessToken
value: $(HelixApiAccessToken) # Needed for internal queues
steps:
Expand Down
2 changes: 1 addition & 1 deletion eng/helix.proj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

<PropertyGroup Condition = "'$(SYSTEM_ACCESSTOKEN)' == ''">
<!-- Local build outside of Azure Pipeline -->
<HelixTargetQueues Condition = "'$(HelixTargetQueues)' == ''">Windows.10.Amd64.Open;Ubuntu.1804.Amd64.Open;OSX.1100.Amd64.Open;Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-sqlserver-amd64-20220131172221-d5c5072</HelixTargetQueues>
<HelixTargetQueues Condition = "'$(HelixTargetQueues)' == ''">Windows.10.Amd64.Open;Ubuntu.1804.Amd64.Open;OSX.1100.Amd64.Open;Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-sqlserver-amd64-20220131172221-d5c5072</HelixTargetQueues>
<EnableAzurePipelinesReporter>false</EnableAzurePipelinesReporter>
<HelixSource>efcore/localbuild/</HelixSource>
<HelixBuild>t001</HelixBuild>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,15 @@ private static string StripId(string commonPrefix)
return commonPrefix;
}

var ignoredCharacterCount = 2;
if (commonPrefix.Length > 4
&& commonPrefix.EndsWith("guid", StringComparison.OrdinalIgnoreCase))
{
ignoredCharacterCount = 4;
}

int i;
for (i = commonPrefix.Length - 3; i >= 0; i--)
for (i = commonPrefix.Length - ignoredCharacterCount - 1; i >= 0; i--)
{
if (char.IsLetterOrDigit(commonPrefix[i]))
{
Expand Down
15 changes: 15 additions & 0 deletions src/EFCore.Relational/Diagnostics/RelationalEventId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ private enum Id
ForeignKeyTpcPrincipalWarning,
TpcStoreGeneratedIdentityWarning,
KeyPropertiesNotMappedToTable,
StoredProcedureConcurrencyTokenNotMapped,

// Update events
BatchReadyForExecution = CoreEventId.RelationalBaseId + 700,
Expand Down Expand Up @@ -872,6 +873,20 @@ private static EventId MakeValidationId(Id id)
public static readonly EventId KeyPropertiesNotMappedToTable =
MakeValidationId(Id.KeyPropertiesNotMappedToTable);

/// <summary>
/// An entity type is mapped to the stored procedure with a concurrency token not mapped to any original value parameter.
/// </summary>
/// <remarks>
/// <para>
/// This event is in the <see cref="DbLoggerCategory.Model.Validation" /> category.
/// </para>
/// <para>
/// This event uses the <see cref="StoredProcedurePropertyEventData" /> payload when used with a <see cref="DiagnosticSource" />.
/// </para>
/// </remarks>
public static readonly EventId StoredProcedureConcurrencyTokenNotMapped =
MakeValidationId(Id.StoredProcedureConcurrencyTokenNotMapped);

/// <summary>
/// A foreign key specifies properties which don't map to the related tables.
/// </summary>
Expand Down
40 changes: 40 additions & 0 deletions src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3122,6 +3122,46 @@ private static string OptionalDependentWithoutIdentifyingPropertyWarning(EventDe
return d.GenerateMessage(p.EntityType.DisplayName());
}

/// <summary>
/// Logs the <see cref="RelationalEventId.StoredProcedureConcurrencyTokenNotMapped" /> event.
/// </summary>
/// <param name="diagnostics">The diagnostics logger to use.</param>
/// <param name="entityType">The entity type that the stored procedure is mapped to.</param>
/// <param name="concurrencyProperty">The property which represents the concurrency token.</param>
/// <param name="storedProcedureName">The stored procedure name.</param>
public static void StoredProcedureConcurrencyTokenNotMapped(
this IDiagnosticsLogger<DbLoggerCategory.Model.Validation> diagnostics,
IEntityType entityType,
IProperty concurrencyProperty,
string storedProcedureName)
{
var definition = RelationalResources.LogStoredProcedureConcurrencyTokenNotMapped(diagnostics);

if (diagnostics.ShouldLog(definition))
{
definition.Log(diagnostics, entityType.DisplayName(), storedProcedureName, concurrencyProperty.Name);
}

if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled))
{
var eventData = new StoredProcedurePropertyEventData(
definition,
StoredProcedureConcurrencyTokenNotMapped,
entityType,
concurrencyProperty,
storedProcedureName);

diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled);
}
}

private static string StoredProcedureConcurrencyTokenNotMapped(EventDefinitionBase definition, EventData payload)
{
var d = (EventDefinition<string, string, string>)definition;
var p = (StoredProcedurePropertyEventData)payload;
return d.GenerateMessage(p.EntityType.DisplayName(), p.StoredProcedureName, p.Property.Name);
}

/// <summary>
/// Logs for the <see cref="RelationalEventId.BatchExecutorFailedToRollbackToSavepoint" /> event.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,15 @@ public abstract class RelationalLoggingDefinitions : LoggingDefinitions
[EntityFrameworkInternal]
public EventDefinitionBase? LogPossibleUnintendedUseOfEquals;

/// <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>
[EntityFrameworkInternal]
public EventDefinitionBase? LogStoredProcedureConcurrencyTokenNotMapped;

/// <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
Expand Down
17 changes: 8 additions & 9 deletions src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,23 +221,23 @@ protected virtual void ValidateStoredProcedures(
if (deleteStoredProcedure != null)
{
AddSproc(StoreObjectType.DeleteStoredProcedure, entityType, storedProcedures);
ValidateSproc(deleteStoredProcedure, mappingStrategy);
ValidateSproc(deleteStoredProcedure, mappingStrategy, logger);
sprocCount++;
}

var insertStoredProcedure = entityType.GetInsertStoredProcedure();
if (insertStoredProcedure != null)
{
AddSproc(StoreObjectType.InsertStoredProcedure, entityType, storedProcedures);
ValidateSproc(insertStoredProcedure, mappingStrategy);
ValidateSproc(insertStoredProcedure, mappingStrategy, logger);
sprocCount++;
}

var updateStoredProcedure = entityType.GetUpdateStoredProcedure();
if (updateStoredProcedure != null)
{
AddSproc(StoreObjectType.UpdateStoredProcedure, entityType, storedProcedures);
ValidateSproc(updateStoredProcedure, mappingStrategy);
ValidateSproc(updateStoredProcedure, mappingStrategy, logger);
sprocCount++;
}

Expand Down Expand Up @@ -288,7 +288,10 @@ static void AddSproc(
}
}

private static void ValidateSproc(IStoredProcedure sproc, string mappingStrategy)
private static void ValidateSproc(
IStoredProcedure sproc,
string mappingStrategy,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
var entityType = sproc.EntityType;
var storeObjectIdentifier = sproc.GetStoreIdentifier();
Expand Down Expand Up @@ -646,11 +649,7 @@ private static void ValidateSproc(IStoredProcedure sproc, string mappingStrategy

if (originalValueProperties.Values.FirstOrDefault(p => p.IsConcurrencyToken) is { } missedConcurrencyToken)
{
throw new InvalidOperationException(
RelationalStrings.StoredProcedureConcurrencyTokenNotMapped(
entityType.DisplayName(),
storeObjectIdentifier.DisplayName(),
missedConcurrencyToken.Name));
logger.StoredProcedureConcurrencyTokenNotMapped(entityType, missedConcurrencyToken, storeObjectIdentifier.DisplayName());
}

if (sproc.ResultColumns.Any(c => c != sproc.FindRowsAffectedResultColumn()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,8 @@ public static CoreOptionsExtension WithDefaultWarningConfiguration(CoreOptionsEx
.TryWithExplicit(RelationalEventId.AmbientTransactionWarning, WarningBehavior.Throw)
.TryWithExplicit(RelationalEventId.IndexPropertiesBothMappedAndNotMappedToTable, WarningBehavior.Throw)
.TryWithExplicit(RelationalEventId.IndexPropertiesMappedToNonOverlappingTables, WarningBehavior.Throw)
.TryWithExplicit(RelationalEventId.ForeignKeyPropertiesMappedToUnrelatedTables, WarningBehavior.Throw));
.TryWithExplicit(RelationalEventId.ForeignKeyPropertiesMappedToUnrelatedTables, WarningBehavior.Throw)
.TryWithExplicit(RelationalEventId.StoredProcedureConcurrencyTokenNotMapped, WarningBehavior.Throw));

/// <summary>
/// Information/metadata for a <see cref="RelationalOptionsExtension" />.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,13 @@ public static IEnumerable<IProperty> GetNonPrincipalSharedNonPkProperties(this I
continue;
}

var propertyMappings = table.FindColumn(property)!.PropertyMappings;
var column = table.FindColumn(property);
if (column == null)
{
continue;
}

var propertyMappings = column.PropertyMappings;
if (propertyMappings.Count() > 1
&& propertyMappings.Any(pm => principalEntityTypes.Contains(pm.TableMapping.EntityType)))
{
Expand Down
33 changes: 25 additions & 8 deletions src/EFCore.Relational/Properties/RelationalStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions src/EFCore.Relational/Properties/RelationalStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,10 @@
<value>The entity type '{entityType}' is an optional dependent using table sharing without any required non shared property that could be used to identify whether the entity exists. If all nullable properties contain a null value in database then an object instance won't be created in the query. Add a required property to create instances with null values for other properties or mark the incoming navigation as required to always create an instance.</value>
<comment>Warning RelationalEventId.OptionalDependentWithoutIdentifyingPropertyWarning string</comment>
</data>
<data name="LogStoredProcedureConcurrencyTokenNotMapped" xml:space="preserve">
<value>The entity type '{entityType}' is mapped to the stored procedure '{sproc}', but the concurrency token '{token}' is not mapped to any original value parameter.</value>
<comment>Warning RelationalEventId.StoredProcedureConcurrencyTokenNotMapped string string string</comment>
</data>
<data name="LogPossibleUnintendedUseOfEquals" xml:space="preserve">
<value>Possible unintended use of method 'Equals' for arguments '{left}' and '{right}' of different types in a query. This comparison will always return false.</value>
<comment>Warning RelationalEventId.QueryPossibleUnintendedUseOfEqualsWarning string string</comment>
Expand Down Expand Up @@ -976,9 +980,6 @@
<data name="SqlQueryUnmappedType" xml:space="preserve">
<value>The element type '{elementType}' used in 'SqlQuery' method is not natively supported by your database provider. Either use a supported element type, or use ModelConfigurationBuilder.DefaultTypeMapping to define a mapping for your type.</value>
</data>
<data name="StoredProcedureConcurrencyTokenNotMapped" xml:space="preserve">
<value>The entity type '{entityType}' is mapped to the stored procedure '{sproc}', but the concurrency token '{token}' is not mapped to any original value parameter.</value>
</data>
<data name="StoredProcedureCurrentValueParameterOnDelete" xml:space="preserve">
<value>Current value parameter '{parameter}' is not allowed on delete stored procedure '{sproc}'. Use HasOriginalValueParameter() instead.</value>
</data>
Expand Down
Loading

0 comments on commit 767bc93

Please sign in to comment.