Browse Source

Allow customizing EF Core configuration of entity&dbContext of an existing module

pull/8898/head
liangshiwei 5 years ago
parent
commit
1fce1dbd3f
  1. 6
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
  2. 14
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpModelBuilderExtensions.cs
  3. 60
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionInfoExtensions.cs
  4. 67
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionManagerExtensions.cs
  5. 39
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/ObjectExtensionInfoEfCoreMappingOptions.cs
  6. 18
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/TestEntityExtensionConfigurator.cs
  7. 7
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs
  8. 6
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingDbContextModelBuilderExtensions.cs
  9. 2
      modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsDbContextModelCreatingExtensions.cs
  10. 4
      modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore/Volo/Abp/BlobStoring/Database/EntityFrameworkCore/BlobStoringDbContextModelCreatingExtensions.cs
  11. 2
      modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContextModelBuilderExtensions.cs
  12. 6
      modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs
  13. 2
      modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs
  14. 2
      modules/feature-management/src/Volo.Abp.FeatureManagement.EntityFrameworkCore/Volo/Abp/FeatureManagement/EntityFrameworkCore/FeatureManagementDbContextModelCreatingExtensions.cs
  15. 2
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs
  16. 2
      modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/IdentityServerDbContextModelCreatingExtensions.cs
  17. 4
      modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementDbContextModelBuilderExtensions.cs
  18. 2
      modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/SettingManagementDbContextModelBuilderExtensions.cs
  19. 2
      modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs

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

@ -31,11 +31,13 @@ using Volo.Abp.Uow;
namespace Volo.Abp.EntityFrameworkCore
{
public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext, ITransientDependency
public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext, ITransientDependency, IHasExtraProperties
where TDbContext : DbContext
{
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; }
protected virtual Guid? CurrentTenantId => CurrentTenant?.Id;
protected virtual bool IsMultiTenantFilterEnabled => DataFilter?.IsEnabled<IMultiTenant>() ?? false;
@ -86,7 +88,7 @@ namespace Volo.Abp.EntityFrameworkCore
protected AbpDbContext(DbContextOptions<TDbContext> options)
: base(options)
{
ExtraProperties = new ExtraPropertyDictionary();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)

14
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpModelBuilderExtensions.cs

@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.EntityFrameworkCore.Modeling
{
public static class AbpModelBuilderExtensions
{
public static void TryConfigureObjectExtensions<TDbContext>(this ModelBuilder modelBuilder)
where TDbContext : DbContext
{
ObjectExtensionManager.Instance.ConfigureEfCoreDbContext<TDbContext>(modelBuilder);
}
}
}

60
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionInfoExtensions.cs

@ -1,11 +1,15 @@
using System;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Volo.Abp.ObjectExtending
{
public static class EfCoreObjectExtensionInfoExtensions
{
public const string EfCoreDbContextConfigurationName = "EfCoreDbContextMapping";
public const string EfCoreEntityConfigurationName = "EfCoreEntityMapping";
[Obsolete("Use MapEfCoreProperty with EntityTypeAndPropertyBuildAction parameters.")]
public static ObjectExtensionInfo MapEfCoreProperty<TProperty>(
[NotNull] this ObjectExtensionInfo objectExtensionInfo,
@ -71,5 +75,61 @@ namespace Volo.Abp.ObjectExtending
}
);
}
public static ObjectExtensionInfo MapEfCoreEntity(
[NotNull] this ObjectExtensionInfo objectExtensionInfo,
[NotNull] Action<EntityTypeBuilder> entityTypeBuildAction)
{
Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));
objectExtensionInfo.Configuration[EfCoreEntityConfigurationName] =
new ObjectExtensionInfoEfCoreMappingOptions(
objectExtensionInfo,
entityTypeBuildAction);
return objectExtensionInfo;
}
public static ObjectExtensionInfo MapEfCoreDbContext(
[NotNull] this ObjectExtensionInfo objectExtensionInfo,
[NotNull] Action<ModelBuilder> modelBuildAction)
{
Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));
objectExtensionInfo.Configuration[EfCoreDbContextConfigurationName] =
new ObjectExtensionInfoEfCoreMappingOptions(
objectExtensionInfo,
modelBuildAction);
return objectExtensionInfo;
}
[CanBeNull]
public static ObjectExtensionInfoEfCoreMappingOptions GetEfCoreEntityMappingOrNull(
[NotNull] this ObjectExtensionInfo objectExtensionInfo)
{
Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));
if (!objectExtensionInfo.Configuration.TryGetValue(EfCoreEntityConfigurationName, out var options))
{
return null;
}
return options as ObjectExtensionInfoEfCoreMappingOptions;
}
[CanBeNull]
public static ObjectExtensionInfoEfCoreMappingOptions GetEfCoreDbContextMappingOrNull(
[NotNull] this ObjectExtensionInfo objectExtensionInfo)
{
Check.NotNull(objectExtensionInfo, nameof(objectExtensionInfo));
if (!objectExtensionInfo.Configuration.TryGetValue(EfCoreDbContextConfigurationName, out var options))
{
return null;
}
return options as ObjectExtensionInfoEfCoreMappingOptions;
}
}
}

67
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionManagerExtensions.cs

@ -1,5 +1,6 @@
using System;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
@ -8,6 +9,45 @@ namespace Volo.Abp.ObjectExtending
{
public static class EfCoreObjectExtensionManagerExtensions
{
public static ObjectExtensionManager MapEfCoreDbContext<TDbContext>(
[NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] Action<ModelBuilder> modelBuilderAction)
where TDbContext: DbContext
{
return objectExtensionManager.AddOrUpdate(
typeof(TDbContext),
options =>
{
options.MapEfCoreDbContext(modelBuilderAction);
});
}
public static ObjectExtensionManager MapEfCoreEntity<TEntity>(
[NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] Action<EntityTypeBuilder> entityTypeBuildAction)
where TEntity : IEntity
{
return MapEfCoreEntity(
objectExtensionManager,
typeof(TEntity),
entityTypeBuildAction);
}
public static ObjectExtensionManager MapEfCoreEntity(
[NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] Type entityType,
[NotNull] Action<EntityTypeBuilder> entityTypeBuildAction)
{
Check.NotNull(objectExtensionManager, nameof(objectExtensionManager));
return objectExtensionManager.AddOrUpdate(
entityType,
options =>
{
options.MapEfCoreEntity(entityTypeBuildAction);
});
}
public static ObjectExtensionManager MapEfCoreProperty<TEntity, TProperty>(
[NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] string propertyName)
@ -32,10 +72,7 @@ namespace Volo.Abp.ObjectExtending
entityType,
propertyType,
propertyName,
options =>
{
options.MapEfCore();
}
options => { options.MapEfCore(); }
);
}
@ -126,6 +163,9 @@ namespace Volo.Abp.ObjectExtending
return;
}
var efCoreEntityMapping = objectExtension.GetEfCoreEntityMappingOrNull();
efCoreEntityMapping?.EntityTypeBuildAction?.Invoke(typeBuilder);
foreach (var property in objectExtension.GetProperties())
{
var efCoreMapping = property.GetEfCoreMappingOrNull();
@ -148,5 +188,24 @@ namespace Volo.Abp.ObjectExtending
#pragma warning restore 618
}
}
public static void ConfigureEfCoreDbContext<TDbContext>(
[NotNull] this ObjectExtensionManager objectExtensionManager,
[NotNull] ModelBuilder modelBuilder)
where TDbContext : DbContext
{
Check.NotNull(objectExtensionManager, nameof(objectExtensionManager));
Check.NotNull(modelBuilder, nameof(modelBuilder));
var objectExtension = objectExtensionManager.GetOrNull(typeof(TDbContext));
if (objectExtension == null)
{
return;
}
var efCoreDbContextMapping = objectExtension.GetEfCoreDbContextMappingOrNull();
efCoreDbContextMapping?.ModelBuildAction?.Invoke(modelBuilder);
}
}
}

39
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/ObjectExtensionInfoEfCoreMappingOptions.cs

@ -0,0 +1,39 @@
using System;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Volo.Abp.ObjectExtending
{
public class ObjectExtensionInfoEfCoreMappingOptions
{
[NotNull]
public ObjectExtensionInfo ObjectExtension { get; }
[CanBeNull]
public Action<EntityTypeBuilder> EntityTypeBuildAction { get; set; }
[CanBeNull]
public Action<ModelBuilder> ModelBuildAction { get; set; }
public ObjectExtensionInfoEfCoreMappingOptions(
[NotNull] ObjectExtensionInfo objectExtension,
[NotNull] Action<EntityTypeBuilder> entityTypeBuildAction)
{
ObjectExtension = Check.NotNull(objectExtension, nameof(objectExtension));
EntityTypeBuildAction = Check.NotNull(entityTypeBuildAction, nameof(entityTypeBuildAction));
EntityTypeBuildAction = entityTypeBuildAction;
}
public ObjectExtensionInfoEfCoreMappingOptions(
[NotNull] ObjectExtensionInfo objectExtension,
[NotNull] Action<ModelBuilder> modelBuildAction)
{
ObjectExtension = Check.NotNull(objectExtension, nameof(objectExtension));
ModelBuildAction = Check.NotNull(modelBuildAction, nameof(modelBuildAction));
ModelBuildAction = modelBuildAction;
}
}
}

18
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/TestEntityExtensionConfigurator.cs

@ -1,6 +1,8 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Volo.Abp.ObjectExtending;
using Volo.Abp.TestApp.Domain;
using Volo.Abp.TestApp.EntityFrameworkCore;
using Volo.Abp.Threading;
namespace Volo.Abp.EntityFrameworkCore.Domain
@ -35,7 +37,21 @@ namespace Volo.Abp.EntityFrameworkCore.Domain
"EnumNumberString"
).MapEfCoreProperty<City, ExtraProperties_Tests.Color>(
"EnumLiteral"
);
).MapEfCoreEntity<City>(b =>
{
b.As<EntityTypeBuilder<City>>()
.Property(x=>x.Name).IsRequired().HasMaxLength(200);
}).MapEfCoreEntity(typeof(Person), b =>
{
b.As<EntityTypeBuilder<Person>>()
.HasIndex(x=>x.Birthday);
});
ObjectExtensionManager.Instance.MapEfCoreDbContext<TestAppDbContext>(b =>
{
b.Entity<City>().Property(x => x.Name).IsRequired();
});
});
}
}

7
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/TestAppDbContext.cs

@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext;
using Volo.Abp.TestApp.Domain;
@ -16,10 +17,10 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore
public DbSet<ThirdDbContextDummyEntity> DummyEntities { get; set; }
public DbSet<EntityWithIntPk> EntityWithIntPks { get; set; }
public DbSet<Author> Author { get; set; }
public TestAppDbContext(DbContextOptions<TestAppDbContext> options)
public TestAppDbContext(DbContextOptions<TestAppDbContext> options)
: base(options)
{
@ -31,6 +32,8 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore
base.OnModelCreating(modelBuilder);
modelBuilder.TryConfigureObjectExtensions<TestAppDbContext>();
modelBuilder.Entity<Phone>(b =>
{
b.HasKey(p => new {p.PersonId, p.Number});

6
modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingDbContextModelBuilderExtensions.cs

@ -39,7 +39,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
if (builder.IsUsingOracle()) { AuditLogConsts.MaxExceptionsLengthValue = 2000; }
b.Property(x => x.Exceptions).HasMaxLength(AuditLogConsts.MaxExceptionsLengthValue).HasColumnName(nameof(AuditLog.Exceptions));
b.Property(x => x.Comments).HasMaxLength(AuditLogConsts.MaxCommentsLength).HasColumnName(nameof(AuditLog.Comments));
b.Property(x => x.ExecutionDuration).HasColumnName(nameof(AuditLog.ExecutionDuration));
b.Property(x => x.ImpersonatorTenantId).HasColumnName(nameof(AuditLog.ImpersonatorTenantId));
@ -67,7 +67,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
b.Property(x => x.Parameters).HasMaxLength(AuditLogActionConsts.MaxParametersLength).HasColumnName(nameof(AuditLogAction.Parameters));
b.Property(x => x.ExecutionTime).HasColumnName(nameof(AuditLogAction.ExecutionTime));
b.Property(x => x.ExecutionDuration).HasColumnName(nameof(AuditLogAction.ExecutionDuration));
b.HasIndex(x => new { x.AuditLogId });
b.HasIndex(x => new { x.TenantId, x.ServiceName, x.MethodName, x.ExecutionTime });
});
@ -104,6 +104,8 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
b.HasIndex(x => new { x.EntityChangeId });
});
builder.TryConfigureObjectExtensions<AbpAuditLoggingDbContext>();
}
}
}

2
modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/BackgroundJobsDbContextModelCreatingExtensions.cs

@ -40,6 +40,8 @@ namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore
b.HasIndex(x => new { x.IsAbandoned, x.NextTryTime });
});
builder.TryConfigureObjectExtensions<BackgroundJobsDbContext>();
}
}
}

4
modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore/Volo/Abp/BlobStoring/Database/EntityFrameworkCore/BlobStoringDbContextModelCreatingExtensions.cs

@ -46,6 +46,8 @@ namespace Volo.Abp.BlobStoring.Database.EntityFrameworkCore
b.HasIndex(x => new {x.TenantId, x.ContainerId, x.Name});
});
builder.TryConfigureObjectExtensions<BlobStoringDbContext>();
}
}
}
}

2
modules/blogging/src/Volo.Blogging.EntityFrameworkCore/Volo/Blogging/EntityFrameworkCore/BloggingDbContextModelBuilderExtensions.cs

@ -107,6 +107,8 @@ namespace Volo.Blogging.EntityFrameworkCore
b.HasKey(x => new { x.PostId, x.TagId });
});
builder.TryConfigureObjectExtensions<BloggingDbContext>();
}
}
}

6
modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs

@ -194,7 +194,7 @@ namespace Volo.CmsKit.EntityFrameworkCore
b.Property(p => p.Slug).IsRequired().HasMaxLength(BlogPostConsts.MaxSlugLength);
b.Property(p => p.ShortDescription).HasMaxLength(BlogPostConsts.MaxShortDescriptionLength);
b.Property(p => p.Content).HasMaxLength(BlogPostConsts.MaxContentLength);
b.HasIndex(x => new { x.Slug, x.BlogId });
});
@ -232,6 +232,8 @@ namespace Volo.CmsKit.EntityFrameworkCore
{
builder.Ignore<MediaDescriptor>();
}
builder.TryConfigureObjectExtensions<CmsKitDbContext>();
}
}
}
}

2
modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs

@ -72,6 +72,8 @@ namespace Volo.Docs.EntityFrameworkCore
b.HasKey(x => new { x.DocumentId, x.Username });
});
builder.TryConfigureObjectExtensions<DocsDbContext>();
}
}
}

2
modules/feature-management/src/Volo.Abp.FeatureManagement.EntityFrameworkCore/Volo/Abp/FeatureManagement/EntityFrameworkCore/FeatureManagementDbContextModelCreatingExtensions.cs

@ -37,6 +37,8 @@ namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
b.HasIndex(x => new { x.Name, x.ProviderName, x.ProviderKey });
});
builder.TryConfigureObjectExtensions<FeatureManagementDbContext>();
}
}
}

2
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs

@ -253,6 +253,8 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
}).IsUnique();
});
}
builder.TryConfigureObjectExtensions<IdentityDbContext>();
}
}
}

2
modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/IdentityServerDbContextModelCreatingExtensions.cs

@ -419,6 +419,8 @@ namespace Volo.Abp.IdentityServer.EntityFrameworkCore
});
#endregion
builder.TryConfigureObjectExtensions<IdentityServerDbContext>();
}
private static bool IsDatabaseProvider(

4
modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementDbContextModelBuilderExtensions.cs

@ -32,6 +32,8 @@ namespace Volo.Abp.PermissionManagement.EntityFrameworkCore
b.HasIndex(x => new {x.Name, x.ProviderName, x.ProviderKey});
});
builder.TryConfigureObjectExtensions<PermissionManagementDbContext>();
}
}
}
}

2
modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/SettingManagementDbContextModelBuilderExtensions.cs

@ -55,6 +55,8 @@ namespace Volo.Abp.SettingManagement.EntityFrameworkCore
b.HasIndex(x => new {x.Name, x.ProviderName, x.ProviderKey});
});
builder.TryConfigureObjectExtensions<SettingManagementDbContext>();
}
}
}

2
modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs

@ -49,6 +49,8 @@ namespace Volo.Abp.TenantManagement.EntityFrameworkCore
b.Property(cs => cs.Name).IsRequired().HasMaxLength(TenantConnectionStringConsts.MaxNameLength);
b.Property(cs => cs.Value).IsRequired().HasMaxLength(TenantConnectionStringConsts.MaxValueLength);
});
builder.TryConfigureObjectExtensions<TenantManagementDbContext>();
}
}
}

Loading…
Cancel
Save