From 219fba719df982a277dcdb219e17bfea6416d072 Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Tue, 25 Dec 2018 15:47:29 +0300 Subject: [PATCH] Resolved #684: Automatically configure audit and other interfaces for EF core model. --- .../Abp/EntityFrameworkCore/AbpDbContext.cs | 112 +++++++++++++++++- .../AbpEntityTypeBuilderExtensions.cs | 41 +++++-- 2 files changed, 138 insertions(+), 15 deletions(-) diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index 1f39d94774..06c5cb4ff4 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Newtonsoft.Json; @@ -315,15 +316,17 @@ namespace Volo.Abp.EntityFrameworkCore protected virtual void ConfigureBaseProperties(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) where TEntity : class { - ConfigureConcurrencyStamp(modelBuilder, mutableEntityType); + ConfigureConcurrencyStampProperty(modelBuilder, mutableEntityType); ConfigureExtraProperties(modelBuilder, mutableEntityType); + ConfigureAuditProperties(modelBuilder, mutableEntityType); + ConfigureTenantIdProperty(modelBuilder, mutableEntityType); ConfigureGlobalFilters(modelBuilder, mutableEntityType); } - protected virtual void ConfigureConcurrencyStamp(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) + protected virtual void ConfigureConcurrencyStampProperty(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) where TEntity : class { - if (!typeof(IHasConcurrencyStamp).GetTypeInfo().IsAssignableFrom(typeof(TEntity))) + if (!typeof(IHasConcurrencyStamp).IsAssignableFrom(typeof(TEntity))) { return; } @@ -339,7 +342,7 @@ namespace Volo.Abp.EntityFrameworkCore protected virtual void ConfigureExtraProperties(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) where TEntity : class { - if (!typeof(IHasExtraProperties).GetTypeInfo().IsAssignableFrom(typeof(TEntity))) + if (!typeof(IHasExtraProperties).IsAssignableFrom(typeof(TEntity))) { return; } @@ -355,6 +358,107 @@ namespace Volo.Abp.EntityFrameworkCore }); } + protected virtual void ConfigureAuditProperties(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) + where TEntity : class + { + if (typeof(TEntity).IsAssignableTo()) + { + modelBuilder.Entity(b => + { + b.Property(x => ((IHasCreationTime)x).CreationTime) + .IsRequired() + .HasColumnName(nameof(IHasCreationTime.CreationTime)); + }); + } + + if (typeof(TEntity).IsAssignableTo()) + { + modelBuilder.Entity(b => + { + b.Property(x => ((IMayHaveCreator)x).CreatorId) + .IsRequired(false) + .HasColumnName(nameof(IMayHaveCreator.CreatorId)); + }); + } + + if (typeof(TEntity).IsAssignableTo()) + { + modelBuilder.Entity(b => + { + b.Property(x => ((IMustHaveCreator)x).CreatorId) + .IsRequired() + .HasColumnName(nameof(IMustHaveCreator.CreatorId)); + }); + } + + if (typeof(TEntity).IsAssignableTo()) + { + modelBuilder.Entity(b => + { + b.Property(x => ((IHasModificationTime)x).LastModificationTime) + .IsRequired(false) + .HasColumnName(nameof(IHasModificationTime.LastModificationTime)); + }); + } + + if (typeof(TEntity).IsAssignableTo()) + { + modelBuilder.Entity(b => + { + b.Property(x => ((IModificationAuditedObject)x).LastModifierId) + .IsRequired(false) + .HasColumnName(nameof(IModificationAuditedObject.LastModifierId)); + }); + } + + if (typeof(TEntity).IsAssignableTo()) + { + modelBuilder.Entity(b => + { + b.Property(x => ((ISoftDelete) x).IsDeleted) + .IsRequired() + .HasDefaultValue(false) + .HasColumnName(nameof(ISoftDelete.IsDeleted)); + }); + } + + if (typeof(TEntity).IsAssignableTo()) + { + modelBuilder.Entity(b => + { + b.Property(x => ((IHasDeletionTime)x).DeletionTime) + .IsRequired(false) + .HasColumnName(nameof(IHasDeletionTime.DeletionTime)); + }); + } + + if (typeof(TEntity).IsAssignableTo()) + { + modelBuilder.Entity(b => + { + b.Property(x => ((IDeletionAuditedObject)x).DeleterId) + .IsRequired(false) + .HasColumnName(nameof(IDeletionAuditedObject.DeleterId)); + }); + } + } + + protected virtual void ConfigureTenantIdProperty(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) + where TEntity : class + { + if (!typeof(TEntity).IsAssignableTo()) + { + return; + } + + modelBuilder.Entity(b => + { + b.Property(x => ((IMultiTenant)x).TenantId) + .IsRequired(false) + .HasColumnName(nameof(IMultiTenant.TenantId)); + }); + } + protected virtual void ConfigureGlobalFilters(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) where TEntity : class { diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs index 200e7a707c..9bb2f9018d 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/Modeling/AbpEntityTypeBuilderExtensions.cs @@ -33,59 +33,76 @@ namespace Volo.Abp.EntityFrameworkCore.Modeling public static void ConfigureSoftDelete(this EntityTypeBuilder b) where T : class, ISoftDelete { - b.Property(x => x.IsDeleted).IsRequired().HasDefaultValue(false).HasColumnName(nameof(ISoftDelete.IsDeleted)); + b.Property(x => x.IsDeleted) + .IsRequired() + .HasDefaultValue(false) + .HasColumnName(nameof(ISoftDelete.IsDeleted)); } public static void ConfigureDeletionTime(this EntityTypeBuilder b) where T : class, IHasDeletionTime { b.ConfigureSoftDelete(); - b.Property(x => x.DeletionTime).IsRequired(false).HasColumnName(nameof(IHasDeletionTime.DeletionTime)); + b.Property(x => x.DeletionTime) + .IsRequired(false) + .HasColumnName(nameof(IHasDeletionTime.DeletionTime)); } public static void ConfigureMayHaveCreator(this EntityTypeBuilder b) where T : class, IMayHaveCreator { - b.Property(x => x.CreatorId).IsRequired(false).HasColumnName(nameof(IMayHaveCreator.CreatorId)); + b.Property(x => x.CreatorId) + .IsRequired(false) + .HasColumnName(nameof(IMayHaveCreator.CreatorId)); } public static void ConfigureMustHaveCreator(this EntityTypeBuilder b) where T : class, IMustHaveCreator { - b.Property(x => x.CreatorId).IsRequired().HasColumnName(nameof(IMustHaveCreator.CreatorId)); + b.Property(x => x.CreatorId) + .IsRequired() + .HasColumnName(nameof(IMustHaveCreator.CreatorId)); } public static void ConfigureDeletionAudited(this EntityTypeBuilder b) where T : class, IDeletionAuditedObject { b.ConfigureDeletionTime(); - b.Property(x => x.DeleterId).IsRequired(false).HasColumnName(nameof(IDeletionAuditedObject.DeleterId)); + b.Property(x => x.DeleterId) + .IsRequired(false) + .HasColumnName(nameof(IDeletionAuditedObject.DeleterId)); } public static void ConfigureCreationTime(this EntityTypeBuilder b) where T : class, IHasCreationTime { - b.Property(x => x.CreationTime).IsRequired().HasColumnName(nameof(IHasCreationTime.CreationTime)); + b.Property(x => x.CreationTime) + .IsRequired() + .HasColumnName(nameof(IHasCreationTime.CreationTime)); } public static void ConfigureCreationAudited(this EntityTypeBuilder b) where T : class, ICreationAuditedObject { b.ConfigureCreationTime(); - b.Property(x => x.CreatorId).IsRequired(false).HasColumnName(nameof(ICreationAuditedObject.CreatorId)); + b.ConfigureMayHaveCreator(); } public static void ConfigureLastModificationTime(this EntityTypeBuilder b) where T : class, IHasModificationTime { - b.Property(x => x.LastModificationTime).IsRequired(false).HasColumnName(nameof(IHasModificationTime.LastModificationTime)); + b.Property(x => x.LastModificationTime) + .IsRequired(false) + .HasColumnName(nameof(IHasModificationTime.LastModificationTime)); } public static void ConfigureModificationAudited(this EntityTypeBuilder b) where T : class, IModificationAuditedObject { b.ConfigureLastModificationTime(); - b.Property(x => x.LastModifierId).IsRequired(false).HasColumnName(nameof(IModificationAuditedObject.LastModifierId)); + b.Property(x => x.LastModifierId) + .IsRequired(false) + .HasColumnName(nameof(IModificationAuditedObject.LastModifierId)); } public static void ConfigureAudited(this EntityTypeBuilder b) @@ -105,9 +122,11 @@ namespace Volo.Abp.EntityFrameworkCore.Modeling public static void ConfigureMultiTenant(this EntityTypeBuilder b) where T : class, IMultiTenant { - b.Property(x => x.TenantId).IsRequired(false).HasColumnName(nameof(IMultiTenant.TenantId)); + b.Property(x => x.TenantId) + .IsRequired(false) + .HasColumnName(nameof(IMultiTenant.TenantId)); } - //TODO: Add other interfaces (IMultiTenant, IAuditedObject...) + //TODO: Add other interfaces (IAuditedObject...) } }