Browse Source

Handle shared types while getting EntityTypeBuilder

pull/23588/head
Halil İbrahim Kalkan 12 months ago
parent
commit
485dd6f1a9
  1. 100
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

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

@ -37,6 +37,7 @@ using Volo.Abp.Reflection;
using Volo.Abp.Timing; using Volo.Abp.Timing;
using Volo.Abp.Uow; using Volo.Abp.Uow;
using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace Volo.Abp.EntityFrameworkCore; namespace Volo.Abp.EntityFrameworkCore;
@ -126,7 +127,7 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
foreach (var entityType in modelBuilder.Model.GetEntityTypes().ToArray()) foreach (var entityType in modelBuilder.Model.GetEntityTypes().ToArray())
{ {
AutoConfigureEntityTypeProperties(modelBuilder, entityType); ConfigureEntityTypeProperties(modelBuilder, entityType);
} }
if (LazyServiceProvider == null || Options == null) if (LazyServiceProvider == null || Options == null)
@ -140,24 +141,23 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
onModelCreatingAction.As<Action<DbContext, ModelBuilder>>().Invoke(this, modelBuilder); onModelCreatingAction.As<Action<DbContext, ModelBuilder>>().Invoke(this, modelBuilder);
} }
} }
protected virtual void AutoConfigureEntityTypeProperties(
ModelBuilder modelBuilder,
IMutableEntityType entityType)
{
ConfigureBasePropertiesMethodInfo
.MakeGenericMethod(entityType.ClrType)
.Invoke(this, new object[] { modelBuilder, entityType });
ConfigureValueConverterMethodInfo
.MakeGenericMethod(entityType.ClrType)
.Invoke(this, new object[] { modelBuilder, entityType });
ConfigureValueGeneratedMethodInfo
.MakeGenericMethod(entityType.ClrType)
.Invoke(this, new object[] { modelBuilder, entityType });
}
protected virtual void ConfigureEntityTypeProperties(
ModelBuilder modelBuilder,
IMutableEntityType entityType)
{
ConfigureBasePropertiesMethodInfo
.MakeGenericMethod(entityType.ClrType)
.Invoke(this, new object[] { modelBuilder, entityType });
ConfigureValueConverterMethodInfo
.MakeGenericMethod(entityType.ClrType)
.Invoke(this, new object[] { modelBuilder, entityType });
ConfigureValueGeneratedMethodInfo
.MakeGenericMethod(entityType.ClrType)
.Invoke(this, new object[] { modelBuilder, entityType });
}
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{ {
@ -770,7 +770,9 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
AuditPropertySetter?.IncrementEntityVersionProperty(entry.Entity); AuditPropertySetter?.IncrementEntityVersionProperty(entry.Entity);
} }
protected virtual void ConfigureBaseProperties<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) protected virtual void ConfigureBaseProperties<TEntity>(
ModelBuilder modelBuilder,
IMutableEntityType mutableEntityType)
where TEntity : class where TEntity : class
{ {
if (mutableEntityType.IsOwned()) if (mutableEntityType.IsOwned())
@ -783,25 +785,44 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
return; return;
} }
modelBuilder.Entity<TEntity>().ConfigureByConvention(); var entityTypeBuilder = CreateEntityTypeBuilderFromMutableEntityType<TEntity>(
modelBuilder,
mutableEntityType
);
entityTypeBuilder.ConfigureByConvention();
ConfigureGlobalFilters<TEntity>(modelBuilder, mutableEntityType, entityTypeBuilder);
}
ConfigureGlobalFilters<TEntity>(modelBuilder, mutableEntityType); protected virtual EntityTypeBuilder<TEntity> CreateEntityTypeBuilderFromMutableEntityType<TEntity>(
ModelBuilder modelBuilder,
IMutableEntityType mutableEntityType) where TEntity : class
{
return mutableEntityType.HasSharedClrType
? modelBuilder.SharedTypeEntity<TEntity>(mutableEntityType.Name)
: modelBuilder.Entity<TEntity>();
} }
protected virtual void ConfigureGlobalFilters<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) protected virtual void ConfigureGlobalFilters<TEntity>(
ModelBuilder modelBuilder,
IMutableEntityType mutableEntityType,
EntityTypeBuilder<TEntity> entityTypeBuilder)
where TEntity : class where TEntity : class
{ {
if (mutableEntityType.BaseType == null && ShouldFilterEntity<TEntity>(mutableEntityType)) if (mutableEntityType.BaseType == null && ShouldFilterEntity<TEntity>(mutableEntityType))
{ {
var filterExpression = CreateFilterExpression<TEntity>(modelBuilder); var filterExpression = CreateFilterExpression<TEntity>(modelBuilder, entityTypeBuilder);
if (filterExpression != null) if (filterExpression != null)
{ {
modelBuilder.Entity<TEntity>().HasAbpQueryFilter(filterExpression); entityTypeBuilder.HasAbpQueryFilter(filterExpression);
} }
} }
} }
protected virtual void ConfigureValueConverter<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) protected virtual void ConfigureValueConverter<TEntity>(
ModelBuilder modelBuilder,
IMutableEntityType mutableEntityType)
where TEntity : class where TEntity : class
{ {
if (mutableEntityType.BaseType != null || if (mutableEntityType.BaseType != null ||
@ -816,6 +837,7 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
{ {
return; return;
} }
foreach (var property in mutableEntityType.GetProperties(). foreach (var property in mutableEntityType.GetProperties().
Where(property => property.PropertyInfo != null && Where(property => property.PropertyInfo != null &&
@ -823,8 +845,12 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
property.PropertyInfo.CanWrite && property.PropertyInfo.CanWrite &&
ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableDateTimeNormalizationAttribute>(property.PropertyInfo) == null)) ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableDateTimeNormalizationAttribute>(property.PropertyInfo) == null))
{ {
modelBuilder var entityTypeBuilder = CreateEntityTypeBuilderFromMutableEntityType<TEntity>(
.Entity<TEntity>() modelBuilder,
mutableEntityType
);
entityTypeBuilder
.Property(property.Name) .Property(property.Name)
.HasConversion(property.ClrType == typeof(DateTime) .HasConversion(property.ClrType == typeof(DateTime)
? new AbpDateTimeValueConverter(Clock) ? new AbpDateTimeValueConverter(Clock)
@ -832,7 +858,9 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
} }
} }
protected virtual void ConfigureValueGenerated<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) protected virtual void ConfigureValueGenerated<TEntity>(
ModelBuilder modelBuilder,
IMutableEntityType mutableEntityType)
where TEntity : class where TEntity : class
{ {
if (!typeof(IEntity<Guid>).IsAssignableFrom(typeof(TEntity))) if (!typeof(IEntity<Guid>).IsAssignableFrom(typeof(TEntity)))
@ -840,7 +868,8 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
return; return;
} }
var idPropertyBuilder = modelBuilder.Entity<TEntity>().Property(x => ((IEntity<Guid>)x).Id); var entityTypeBuilder = CreateEntityTypeBuilderFromMutableEntityType<TEntity>(modelBuilder, mutableEntityType);
var idPropertyBuilder = entityTypeBuilder.Property(x => ((IEntity<Guid>)x).Id);
if (idPropertyBuilder.Metadata.PropertyInfo!.IsDefined(typeof(DatabaseGeneratedAttribute), true)) if (idPropertyBuilder.Metadata.PropertyInfo!.IsDefined(typeof(DatabaseGeneratedAttribute), true))
{ {
return; return;
@ -864,25 +893,30 @@ public abstract class AbpDbContext<TDbContext> : DbContext, IAbpEfCoreDbContext,
return false; return false;
} }
protected virtual Expression<Func<TEntity, bool>>? CreateFilterExpression<TEntity>(ModelBuilder modelBuilder) protected virtual Expression<Func<TEntity, bool>>? CreateFilterExpression<TEntity>(
ModelBuilder modelBuilder,
EntityTypeBuilder<TEntity> entityTypeBuilder)
where TEntity : class where TEntity : class
{ {
Expression<Func<TEntity, bool>>? expression = null; Expression<Func<TEntity, bool>>? expression = null;
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
{ {
var softDeleteColumnName = modelBuilder.Entity<TEntity>().Metadata.FindProperty(nameof(ISoftDelete.IsDeleted))?.GetColumnName() ?? "IsDeleted"; var softDeleteColumnName = entityTypeBuilder.Metadata.FindProperty(nameof(ISoftDelete.IsDeleted))?.GetColumnName() ?? "IsDeleted";
expression = e => !IsSoftDeleteFilterEnabled || !EF.Property<bool>(e, softDeleteColumnName); expression = e => !IsSoftDeleteFilterEnabled || !EF.Property<bool>(e, softDeleteColumnName);
if (UseDbFunction()) if (UseDbFunction())
{ {
expression = e => AbpEfCoreDataFilterDbFunctionMethods.SoftDeleteFilter(((ISoftDelete)e).IsDeleted, true); expression = e => AbpEfCoreDataFilterDbFunctionMethods.SoftDeleteFilter(((ISoftDelete)e).IsDeleted, true);
modelBuilder.ConfigureSoftDeleteDbFunction(AbpEfCoreDataFilterDbFunctionMethods.SoftDeleteFilterMethodInfo, this.GetService<AbpEfCoreCurrentDbContext>()); modelBuilder.ConfigureSoftDeleteDbFunction(
AbpEfCoreDataFilterDbFunctionMethods.SoftDeleteFilterMethodInfo,
this.GetService<AbpEfCoreCurrentDbContext>()
);
} }
} }
if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity))) if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity)))
{ {
var multiTenantColumnName = modelBuilder.Entity<TEntity>().Metadata.FindProperty(nameof(IMultiTenant.TenantId))?.GetColumnName() ?? "TenantId"; var multiTenantColumnName = entityTypeBuilder.Metadata.FindProperty(nameof(IMultiTenant.TenantId))?.GetColumnName() ?? "TenantId";
Expression<Func<TEntity, bool>> multiTenantFilter = e => !IsMultiTenantFilterEnabled || EF.Property<Guid>(e, multiTenantColumnName) == CurrentTenantId; Expression<Func<TEntity, bool>> multiTenantFilter = e => !IsMultiTenantFilterEnabled || EF.Property<Guid>(e, multiTenantColumnName) == CurrentTenantId;
if (UseDbFunction()) if (UseDbFunction())
{ {

Loading…
Cancel
Save