Skip to content

Commit

Permalink
Implement stored procedure update mapping (#28553)
Browse files Browse the repository at this point in the history
* Remove transaction suppression metadata

* Implement stored procedure update mapping

Closes #245
Closes #28435

Co-authored-by: Andriy Svyryd <AndriySvyryd@users.noreply.github.com>

Co-authored-by: Andriy Svyryd <AndriySvyryd@users.noreply.github.com>
  • Loading branch information
roji and AndriySvyryd committed Aug 13, 2022
1 parent ba92471 commit 099b2a9
Show file tree
Hide file tree
Showing 88 changed files with 2,737 additions and 703 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,7 @@ private void Create(IStoredProcedure storedProcedure, string sprocVariable, CSha
.Append(parameters.TargetName).AppendLine(",")
.Append(code.Literal(storedProcedure.Name)).AppendLine(",")
.Append(code.Literal(storedProcedure.Schema)).AppendLine(",")
.Append(code.Literal(storedProcedure.IsRowsAffectedReturned)).AppendLine(",")
.Append(code.Literal(storedProcedure.AreTransactionsSuppressed))
.Append(code.Literal(storedProcedure.IsRowsAffectedReturned))
.AppendLine(");")
.DecrementIndent()
.AppendLine();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1153,7 +1153,7 @@ private static bool IsOptionalSharingDependent(

return optional ?? (entityType.BaseType != null && entityType.FindDiscriminatorProperty() != null);
}

/// <summary>
/// Returns the comment for the column this property is mapped to.
/// </summary>
Expand Down
10 changes: 10 additions & 0 deletions src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,16 @@ private static void ValidateSproc(IStoredProcedure sproc, string mappingStrategy
_ => new Dictionary<string, IProperty>()
};

if (mappingStrategy == RelationalAnnotationNames.TptMappingStrategy
&& storeObjectIdentifier.StoreObjectType == StoreObjectType.InsertStoredProcedure
&& entityType.BaseType?.GetInsertStoredProcedure() != null)
{
foreach (var property in primaryKey.Properties)
{
storeGeneratedProperties.Remove(property.Name);
}
}

var resultColumnNames = new HashSet<string>();
foreach (var resultColumn in sproc.ResultColumns)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,20 +156,4 @@ public interface IConventionStoredProcedureBuilder : IConventionAnnotatableBuild
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
/// <returns><see langword="true" /> if the column of the result can be used for the stored procedure.</returns>
bool CanHaveRowsAffectedResultColumn(string propertyName, bool fromDataAnnotation = false);

/// <summary>
/// Prevents automatically creating a transaction when executing this stored procedure.
/// </summary>
/// <param name="suppress">A value indicating whether the automatic transactions should be prevented.</param>
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
/// <returns>The same builder instance so that multiple configuration calls can be chained.</returns>
IConventionStoredProcedureBuilder? SuppressTransactions(bool suppress, bool fromDataAnnotation = false);

/// <summary>
/// Returns a value indicating whether the transaction suppression can be set for stored procedure.
/// </summary>
/// <param name="suppress">A value indicating whether the automatic transactions should be prevented.</param>
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
/// <returns><see langword="true" /> if the column of the result can be used for the stored procedure.</returns>
bool CanSetSuppressTransactions(bool suppress, bool fromDataAnnotation = false);
}
Original file line number Diff line number Diff line change
Expand Up @@ -219,17 +219,6 @@ public virtual OwnedNavigationStoredProcedureBuilder HasRowsAffectedReturnValue(
return this;
}

/// <summary>
/// Prevents automatically creating a transaction when executing this stored procedure.
/// </summary>
/// <param name="suppress">A value indicating whether the automatic transactions should be prevented.</param>
/// <returns>The same builder instance so that multiple configuration calls can be chained.</returns>
public virtual OwnedNavigationStoredProcedureBuilder SuppressTransactions(bool suppress = true)
{
Builder.SuppressTransactions(suppress, ConfigurationSource.Explicit);
return this;
}

/// <summary>
/// Adds or updates an annotation on the stored procedure. If an annotation with the key specified in
/// <paramref name="annotation" /> already exists, its value will be updated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,14 +231,6 @@ public virtual OwnedNavigationStoredProcedureBuilder<TOwnerEntity, TDependentEnt
public new virtual OwnedNavigationStoredProcedureBuilder<TOwnerEntity, TDependentEntity> HasRowsAffectedReturnValue(bool rowsAffectedReturned = true)
=> (OwnedNavigationStoredProcedureBuilder<TOwnerEntity, TDependentEntity>)base.HasRowsAffectedReturnValue(rowsAffectedReturned);

/// <summary>
/// Prevents automatically creating a transaction when executing this stored procedure.
/// </summary>
/// <param name="suppress">A value indicating whether the automatic transactions should be prevented.</param>
/// <returns>The same builder instance so that multiple configuration calls can be chained.</returns>
public new virtual OwnedNavigationStoredProcedureBuilder<TOwnerEntity, TDependentEntity> SuppressTransactions(bool suppress = true)
=> (OwnedNavigationStoredProcedureBuilder<TOwnerEntity, TDependentEntity>)base.SuppressTransactions(suppress);

/// <summary>
/// Adds or updates an annotation on the stored procedure. If an annotation with the key specified in
/// <paramref name="annotation" /> already exists, its value will be updated.
Expand Down
11 changes: 0 additions & 11 deletions src/EFCore.Relational/Metadata/Builders/StoredProcedureBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,6 @@ public virtual StoredProcedureBuilder HasRowsAffectedReturnValue(bool rowsAffect
return this;
}

/// <summary>
/// Prevents automatically creating a transaction when executing this stored procedure.
/// </summary>
/// <param name="suppress">A value indicating whether the automatic transactions should be prevented.</param>
/// <returns>The same builder instance so that multiple configuration calls can be chained.</returns>
public virtual StoredProcedureBuilder SuppressTransactions(bool suppress = true)
{
Builder.SuppressTransactions(suppress, ConfigurationSource.Explicit);
return this;
}

/// <summary>
/// Adds or updates an annotation on the stored procedure. If an annotation with the key specified in
/// <paramref name="annotation" /> already exists, its value will be updated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,14 +314,6 @@ public virtual StoredProcedureBuilder<TEntity> HasResultColumn<TDerivedEntity, T
public new virtual StoredProcedureBuilder<TEntity> HasRowsAffectedReturnValue(bool rowsAffectedReturned = true)
=> (StoredProcedureBuilder<TEntity>)base.HasRowsAffectedReturnValue(rowsAffectedReturned);

/// <summary>
/// Prevents automatically creating a transaction when executing this stored procedure.
/// </summary>
/// <param name="suppress">A value indicating whether the automatic transactions should be prevented.</param>
/// <returns>The same builder instance so that multiple configuration calls can be chained.</returns>
public new virtual StoredProcedureBuilder<TEntity> SuppressTransactions(bool suppress = true)
=> (StoredProcedureBuilder<TEntity>)base.SuppressTransactions(suppress);

/// <summary>
/// Adds or updates an annotation on the stored procedure. If an annotation with the key specified in
/// <paramref name="annotation" /> already exists, its value will be updated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,8 +498,7 @@ private RuntimeStoredProcedure Create(IStoredProcedure storedProcedure, RuntimeE
runtimeEntityType,
storedProcedure.Name,
storedProcedure.Schema,
storedProcedure.IsRowsAffectedReturned,
storedProcedure.AreTransactionsSuppressed);
storedProcedure.IsRowsAffectedReturned);

foreach (var parameter in storedProcedure.Parameters)
{
Expand Down
8 changes: 0 additions & 8 deletions src/EFCore.Relational/Metadata/IColumn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,6 @@ bool TryGetDefaultValue(out object? defaultValue)
=> PropertyMappings.First().Property
.GetCollation(StoreObjectIdentifier.Table(Table.Name, Table.Schema));

/// <summary>
/// Gets the <see cref="ValueComparer" /> for this column.
/// </summary>
/// <returns>The comparer.</returns>
ValueComparer ProviderValueComparer
=> PropertyMappings.First().Property
.GetProviderValueComparer();

/// <summary>
/// Returns the property mapping for the given entity type.
/// </summary>
Expand Down
8 changes: 8 additions & 0 deletions src/EFCore.Relational/Metadata/IColumnBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ public interface IColumnBase : IAnnotatable
/// </summary>
IReadOnlyList<IColumnMappingBase> PropertyMappings { get; }

/// <summary>
/// Gets the <see cref="ValueComparer" /> for this column.
/// </summary>
/// <returns>The comparer.</returns>
ValueComparer ProviderValueComparer
=> PropertyMappings.First().Property
.GetProviderValueComparer();

/// <summary>
/// Returns the property mapping for the given entity type.
/// </summary>
Expand Down
14 changes: 0 additions & 14 deletions src/EFCore.Relational/Metadata/IConventionStoredProcedure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,4 @@ public interface IConventionStoredProcedure : IReadOnlyStoredProcedure, IConvent
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
/// <returns>The configured value.</returns>
bool SetIsRowsAffectedReturned(bool rowsAffectedReturned, bool fromDataAnnotation = false);

/// <summary>
/// Prevents automatically creating a transaction when executing this stored procedure.
/// </summary>
/// <param name="areTransactionsSuppressed">A value indicating whether the automatic transactions should be prevented.</param>
/// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
/// <returns>The configured value.</returns>
bool SetAreTransactionsSuppressed(bool areTransactionsSuppressed, bool fromDataAnnotation = false);

/// <summary>
/// Gets the configuration source for <see cref="IReadOnlyStoredProcedure.Schema" />.
/// </summary>
/// <returns>The configuration source for <see cref="IReadOnlyStoredProcedure.Schema" />.</returns>
ConfigurationSource? GetAreTransactionsSuppressedConfigurationSource();
}
6 changes: 0 additions & 6 deletions src/EFCore.Relational/Metadata/IMutableStoredProcedure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,6 @@ public interface IMutableStoredProcedure : IReadOnlyStoredProcedure, IMutableAnn
/// </summary>
new IMutableEntityType EntityType { get; }

/// <summary>
/// Returns a value indicating whether automatic creation of transactions is disabled when executing this stored procedure.
/// </summary>
/// <returns>The configured value.</returns>
new bool AreTransactionsSuppressed { get; set; }

/// <summary>
/// Gets or sets a value indicating whether this stored procedure returns the number of rows affected.
/// </summary>
Expand Down
5 changes: 0 additions & 5 deletions src/EFCore.Relational/Metadata/IReadOnlyStoredProcedure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ public interface IReadOnlyStoredProcedure : IReadOnlyAnnotatable
/// </summary>
IReadOnlyEntityType EntityType { get; }

/// <summary>
/// Returns a value indicating whether automatic creation of transactions is disabled when executing this stored procedure.
/// </summary>
bool AreTransactionsSuppressed { get; }

/// <summary>
/// Gets a value indicating whether this stored procedure returns the number of rows affected.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public interface IStoreStoredProcedureParameter : IColumnBase
/// Gets the property mappings.
/// </summary>
new IReadOnlyList<IStoredProcedureParameterMapping> PropertyMappings { get; }

/// <summary>
/// Gets the direction of the parameter.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public interface IStoreStoredProcedureResultColumn : IColumnBase
/// </summary>
new IReadOnlyList<IStoredProcedureResultColumnMapping> PropertyMappings { get; }

/// <summary>
/// Gets the 0-based position of the result column in the declaring stored procedure's result set.
/// </summary>
int Position { get; }

/// <summary>
/// Returns the property mapping for the given entity type.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,33 +410,6 @@ public virtual bool CanHaveRowsAffectedReturn(bool rowsAffectedReturned, Configu
=> Metadata.IsRowsAffectedReturned == rowsAffectedReturned
|| configurationSource.Overrides(Metadata.GetConfigurationSource());

/// <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 virtual InternalStoredProcedureBuilder? SuppressTransactions(bool suppress, ConfigurationSource configurationSource)
{
if (!CanSuppressTransactions(suppress, configurationSource))
{
return null;
}

Metadata.SetAreTransactionsSuppressed(suppress, configurationSource);
return this;
}

/// <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 virtual bool CanSuppressTransactions(bool suppress, ConfigurationSource configurationSource)
=> Metadata.AreTransactionsSuppressed == suppress
|| configurationSource.Overrides(Metadata.GetAreTransactionsSuppressedConfigurationSource());

IConventionStoredProcedure IConventionStoredProcedureBuilder.Metadata
{
[DebuggerStepThrough]
Expand Down Expand Up @@ -524,15 +497,4 @@ bool IConventionStoredProcedureBuilder.CanHaveResultColumn(string propertyName,
[DebuggerStepThrough]
bool IConventionStoredProcedureBuilder.CanHaveRowsAffectedResultColumn(string propertyName, bool fromDataAnnotation)
=> CanHaveRowsAffectedResultColumn(fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);

/// <inheritdoc />
[DebuggerStepThrough]
IConventionStoredProcedureBuilder? IConventionStoredProcedureBuilder.SuppressTransactions(bool suppress, bool fromDataAnnotation)
=> SuppressTransactions(suppress, fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);

/// <inheritdoc />
[DebuggerStepThrough]
bool IConventionStoredProcedureBuilder.CanSetSuppressTransactions(bool suppress, bool fromDataAnnotation)
=> CanSuppressTransactions(suppress,
fromDataAnnotation ? ConfigurationSource.DataAnnotation : ConfigurationSource.Convention);
}
2 changes: 1 addition & 1 deletion src/EFCore.Relational/Metadata/Internal/JsonColumn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ bool IColumn.IsRowVersion
/// 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>
ValueComparer IColumn.ProviderValueComparer
ValueComparer IColumnBase.ProviderValueComparer
=> _providerValueComparer;

/// <summary>
Expand Down
Loading

0 comments on commit 099b2a9

Please sign in to comment.