Skip to content

Commit

Permalink
Add a custom convention which adds a blank trigger to all tables
Browse files Browse the repository at this point in the history
Fixes #27531
  • Loading branch information
AndriySvyryd committed Aug 16, 2022
1 parent a999af7 commit 7dd7b8a
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 6 deletions.
26 changes: 26 additions & 0 deletions src/EFCore/Extensions/Internal/DbContextExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// ReSharper disable CheckNamespace

namespace Microsoft.EntityFrameworkCore.Internal;

/// <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 static class DbContextExtensions
{
/// <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 static void ConfigureConventions(
this DbContext context,
ModelConfigurationBuilder configurationBuilder)
=> context.ConfigureConventions(configurationBuilder);
}
45 changes: 45 additions & 0 deletions src/EFCore/Metadata/Conventions/BlankTriggerAddingConvention.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.EntityFrameworkCore.Metadata.Conventions;

/// <summary>
/// A convention that makes sure there is a trigger on all entity types.
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-conventions">Model building conventions</see> for more information and examples.
/// </remarks>
public class BlankTriggerAddingConvention : IModelFinalizingConvention
{
/// <summary>
/// Creates a new instance of <see cref="BlankTriggerAddingConvention" />.
/// </summary>
/// <param name="dependencies">Parameter object containing dependencies for this convention.</param>
public BlankTriggerAddingConvention(ProviderConventionSetBuilderDependencies dependencies)
{
Dependencies = dependencies;
}

/// <summary>
/// Dependencies for this service.
/// </summary>
protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; }

/// <summary>
/// Called when a model is being finalized.
/// </summary>
/// <param name="modelBuilder">The builder for the model.</param>
/// <param name="context">Additional information associated with convention execution.</param>
public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
{
foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
{
if (entityType.GetDeclaredTriggers().Any())
{
continue;
}

entityType.AddTrigger(entityType.ShortName() + "_Trigger");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.EntityFrameworkCore.Internal;

namespace Microsoft.EntityFrameworkCore.TestUtilities;

public class TestModelSource : ModelSource
Expand All @@ -26,6 +28,7 @@ protected override IModel CreateModel(
var modelConfigurationBuilder = new ModelConfigurationBuilder(
conventionSetBuilder.CreateConventionSet(),
context.GetInfrastructure());
context.ConfigureConventions(modelConfigurationBuilder);
_configureConventions?.Invoke(modelConfigurationBuilder);
var modelBuilder = modelConfigurationBuilder.CreateModelBuilder(modelDependencies);

Expand Down
12 changes: 6 additions & 6 deletions test/EFCore.SqlServer.FunctionalTests/SqlServerTriggersTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity<Product>(
eb =>
{
eb.ToTable(tb =>
{
tb.HasTrigger("TRG_InsertProduct");
tb.HasTrigger("TRG_UpdateProduct");
tb.HasTrigger("TRG_DeleteProduct");
});
eb.Property(e => e.Version)
.ValueGeneratedOnAddOrUpdate()
.IsConcurrencyToken();
Expand All @@ -122,6 +116,12 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity<ProductBackup>()
.Property(e => e.Id).ValueGeneratedNever();
}

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder.Conventions.Add(p =>
new BlankTriggerAddingConvention(p.GetService<ProviderConventionSetBuilderDependencies>()));
}
}

protected class Product
Expand Down

0 comments on commit 7dd7b8a

Please sign in to comment.