Browse Source

Merge pull request #19241 from abpframework/salihozkara/abpDbContext2

Allow extending `ConfigureConventions` and `OnModelCreating`.
pull/19252/head
maliming 3 years ago
committed by GitHub
parent
commit
0f18c0e946
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 24
      docs/en/Entity-Framework-Core.md
  2. 30
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
  3. 61
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs

24
docs/en/Entity-Framework-Core.md

@ -139,6 +139,30 @@ Configure<AbpDbContextOptions>(options =>
});
````
Add actions for the `ConfigureConventions` and `OnModelCreating` methods of the `DbContext` as shown below:
````csharp
options.DefaultConventionAction = (dbContext, builder) =>
{
// This action is called for ConfigureConventions method of all DbContexts.
};
options.ConfigureConventions<YourDbContext>((dbContext, builder) =>
{
// This action is called for ConfigureConventions method of specific DbContext.
});
options.DefaultOnModelCreatingAction = (dbContext, builder) =>
{
// This action is called for OnModelCreating method of all DbContexts.
};
options.ConfigureOnModelCreating<YourDbContext>((dbContext, builder) =>
{
// This action is called for OnModelCreating method of specific DbContext.
});
````
If you have a single `DbContext` or you have multiple `DbContext`s but want to use the same DBMS and configuration for all, you can leave it as is. However, if you need to configure a different DBMS or customize the configuration for a specific `DbContext`, you can specify it as shown below:
````csharp

30
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

@ -14,6 +14,7 @@ using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
@ -69,6 +70,8 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
public ILogger<AbpDbContext<TDbContext>> Logger => LazyServiceProvider.LazyGetService<ILogger<AbpDbContext<TDbContext>>>(NullLogger<AbpDbContext<TDbContext>>.Instance);
public IOptions<AbpDbContextOptions> Options => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpDbContextOptions>>();
private static readonly MethodInfo ConfigureBasePropertiesMethodInfo
= typeof(AbpDbContext<TDbContext>)
.GetMethod(
@ -115,6 +118,33 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
.MakeGenericMethod(entityType.ClrType)
.Invoke(this, new object[] { modelBuilder, entityType });
}
if (LazyServiceProvider == null || Options == null)
{
return;
}
Options.Value.DefaultOnModelCreatingAction?.Invoke(this, modelBuilder);
foreach (var onModelCreatingAction in Options.Value.OnModelCreatingActions.GetOrDefault(typeof(TDbContext)) ?? [])
{
onModelCreatingAction.As<Action<DbContext, ModelBuilder>>().Invoke(this, modelBuilder);
}
}
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
base.ConfigureConventions(configurationBuilder);
if (LazyServiceProvider == null || Options == null)
{
return;
}
Options.Value.DefaultConventionAction?.Invoke(this, configurationBuilder);
foreach (var conventionAction in Options.Value.ConventionActions.GetOrDefault(typeof(TDbContext)) ?? [])
{
conventionAction.As<Action<DbContext, ModelConfigurationBuilder>>().Invoke(this, configurationBuilder);
}
}
protected virtual void TrySetDatabaseProvider(ModelBuilder modelBuilder)

61
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContextOptions.cs

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EntityFrameworkCore.DependencyInjection;
using Volo.Abp.MultiTenancy;
@ -20,12 +21,22 @@ public class AbpDbContextOptions
internal Dictionary<MultiTenantDbContextType, Type> DbContextReplacements { get; }
internal Action<DbContext, ModelConfigurationBuilder>? DefaultConventionAction { get; set; }
internal Dictionary<Type, List<object>> ConventionActions { get; }
internal Action<DbContext, ModelBuilder>? DefaultOnModelCreatingAction { get; set; }
internal Dictionary<Type, List<object>> OnModelCreatingActions { get; }
public AbpDbContextOptions()
{
DefaultPreConfigureActions = new List<Action<AbpDbContextConfigurationContext>>();
PreConfigureActions = new Dictionary<Type, List<object>>();
ConfigureActions = new Dictionary<Type, object>();
DbContextReplacements = new Dictionary<MultiTenantDbContextType, Type>();
ConventionActions = new Dictionary<Type, List<object>>();
OnModelCreatingActions = new Dictionary<Type, List<object>>();
}
public void PreConfigure([NotNull] Action<AbpDbContextConfigurationContext> action)
@ -42,6 +53,56 @@ public class AbpDbContextOptions
DefaultConfigureAction = action;
}
public void ConfigureDefaultConvention([NotNull] Action<DbContext, ModelConfigurationBuilder> action)
{
Check.NotNull(action, nameof(action));
DefaultConventionAction = action;
}
public void ConfigureConventions<TDbContext>([NotNull] Action<TDbContext, ModelConfigurationBuilder> action)
where TDbContext : AbpDbContext<TDbContext>
{
Check.NotNull(action, nameof(action));
var actions = ConventionActions.GetOrDefault(typeof(TDbContext));
if (actions == null)
{
ConventionActions[typeof(TDbContext)] = new List<object>
{
new Action<DbContext, ModelConfigurationBuilder>((dbContext, builder) => action((TDbContext)dbContext, builder))
};
return;
}
actions.Add(action);
}
public void ConfigureDefaultOnModelCreating([NotNull] Action<DbContext, ModelBuilder> action)
{
Check.NotNull(action, nameof(action));
DefaultOnModelCreatingAction = action;
}
public void ConfigureOnModelCreating<TDbContext>([NotNull] Action<TDbContext, ModelBuilder> action)
where TDbContext : AbpDbContext<TDbContext>
{
Check.NotNull(action, nameof(action));
var actions = OnModelCreatingActions.GetOrDefault(typeof(TDbContext));
if (actions == null)
{
OnModelCreatingActions[typeof(TDbContext)] = new List<object>
{
new Action<DbContext, ModelBuilder>((dbContext, builder) => action((TDbContext)dbContext, builder))
};
return;
}
actions.Add(action);
}
public bool IsConfiguredDefault()
{
return DefaultConfigureAction != null;

Loading…
Cancel
Save