Resolved #682: Automatically configure IHasExtraProperties for entities in EF Core.

pull/691/head
Halil ibrahim Kalkan 6 years ago
parent b1fbafff19
commit 6401c37bc1

@ -11,6 +11,7 @@ using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
@ -49,10 +50,10 @@ namespace Volo.Abp.EntityFrameworkCore
public ILogger<AbpDbContext<TDbContext>> Logger { get; set; }
private static readonly MethodInfo ConfigureGlobalFiltersMethodInfo
private static readonly MethodInfo ConfigureBasePropertiesMethodInfo
= typeof(AbpDbContext<TDbContext>)
.GetMethod(
nameof(ConfigureGlobalFilters),
nameof(ConfigureBaseProperties),
BindingFlags.Instance | BindingFlags.NonPublic
);
@ -71,9 +72,7 @@ namespace Volo.Abp.EntityFrameworkCore
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
ConfigureConcurrencyStamp(entityType);
ConfigureGlobalFiltersMethodInfo
ConfigureBasePropertiesMethodInfo
.MakeGenericMethod(entityType.ClrType)
.Invoke(this, new object[] { modelBuilder, entityType });
}
@ -155,19 +154,6 @@ namespace Volo.Abp.EntityFrameworkCore
}
}
protected virtual void ConfigureConcurrencyStamp(IMutableEntityType entityType)
{
if (!typeof(IHasConcurrencyStamp).GetTypeInfo().IsAssignableFrom(entityType.ClrType))
{
return;
}
entityType
.GetProperties()
.First(p => p.Name == nameof(IHasConcurrencyStamp.ConcurrencyStamp))
.IsConcurrencyToken = true;
}
protected virtual EntityChangeReport ApplyAbpConcepts()
{
var changeReport = new EntityChangeReport();
@ -326,10 +312,53 @@ namespace Volo.Abp.EntityFrameworkCore
AuditPropertySetter.SetDeletionProperties(entry.Entity);
}
protected void ConfigureGlobalFilters<TEntity>(ModelBuilder modelBuilder, IMutableEntityType entityType)
protected virtual void ConfigureBaseProperties<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType)
where TEntity : class
{
ConfigureConcurrencyStamp<TEntity>(modelBuilder, mutableEntityType);
ConfigureExtraProperties<TEntity>(modelBuilder, mutableEntityType);
ConfigureGlobalFilters<TEntity>(modelBuilder, mutableEntityType);
}
protected virtual void ConfigureConcurrencyStamp<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType)
where TEntity : class
{
if (!typeof(IHasConcurrencyStamp).GetTypeInfo().IsAssignableFrom(typeof(TEntity)))
{
return;
}
modelBuilder.Entity<TEntity>(b =>
{
b.Property(x => ((IHasConcurrencyStamp) x).ConcurrencyStamp)
.IsConcurrencyToken()
.HasColumnName(nameof(IHasConcurrencyStamp.ConcurrencyStamp));
});
}
protected virtual void ConfigureExtraProperties<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType)
where TEntity : class
{
if (!typeof(IHasExtraProperties).GetTypeInfo().IsAssignableFrom(typeof(TEntity)))
{
return;
}
modelBuilder.Entity<TEntity>(b =>
{
b.Property(x => ((IHasExtraProperties) x).ExtraProperties)
.HasConversion(
d => JsonConvert.SerializeObject(d, Formatting.None),
s => JsonConvert.DeserializeObject<Dictionary<string, object>>(s)
)
.HasColumnName(nameof(IHasExtraProperties.ExtraProperties));
});
}
protected virtual void ConfigureGlobalFilters<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType)
where TEntity : class
{
if (entityType.BaseType == null && ShouldFilterEntity<TEntity>(entityType))
if (mutableEntityType.BaseType == null && ShouldFilterEntity<TEntity>(mutableEntityType))
{
var filterExpression = CreateFilterExpression<TEntity>();
if (filterExpression != null)

@ -4,12 +4,21 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Newtonsoft.Json;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.EntityFrameworkCore.Modeling
{
public static class AbpEntityTypeBuilderExtensions
{
public static void ConfigureConcurrencyStamp<T>(this EntityTypeBuilder<T> b)
where T : class, IHasConcurrencyStamp
{
b.Property(x => x.ConcurrencyStamp)
.IsConcurrencyToken()
.HasColumnName(nameof(IHasConcurrencyStamp.ConcurrencyStamp));
}
public static void ConfigureExtraProperties<T>(this EntityTypeBuilder<T> b)
where T : class, IHasExtraProperties
{

@ -21,12 +21,6 @@ namespace Volo.Abp.EntityFrameworkCore.TestApp.SecondContext
modelBuilder.Entity<PhoneInSecondDbContext>(b =>
{
b.HasKey(p => new { p.PersonId, p.Number });
b.ConfigureExtraProperties();
});
modelBuilder.Entity<BookInSecondDbContext>(b =>
{
b.ConfigureExtraProperties();
});
}
}

@ -1,5 +1,4 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.EntityFrameworkCore.TestApp.SecondContext;
using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext;
using Volo.Abp.TestApp.Domain;
@ -30,26 +29,6 @@ namespace Volo.Abp.EntityFrameworkCore
{
b.HasKey(p => new { p.PersonId, p.Number });
});
modelBuilder.Entity<Person>(b =>
{
b.ConfigureExtraProperties();
});
modelBuilder.Entity<City>(b =>
{
b.ConfigureExtraProperties();
});
modelBuilder.Entity<ThirdDbContextDummyEntity>(b =>
{
b.ConfigureExtraProperties();
});
modelBuilder.Entity<BookInSecondDbContext>(b =>
{
b.ConfigureExtraProperties();
});
}
}
}

@ -1,6 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.EntityFrameworkCore.TestApp.ThirdDbContext;
using Volo.Abp.TestApp.Domain;
@ -24,25 +23,10 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Person>(b =>
{
b.ConfigureExtraProperties();
});
modelBuilder.Entity<Phone>(b =>
{
b.HasKey(p => new {p.PersonId, p.Number});
});
modelBuilder.Entity<City>(b =>
{
b.ConfigureExtraProperties();
});
modelBuilder.Entity<ThirdDbContextDummyEntity>(b =>
{
b.ConfigureExtraProperties();
});
}
}
}

@ -29,8 +29,6 @@ namespace Volo.Docs.EntityFrameworkCore
b.Property(x => x.DefaultDocumentName).IsRequired().HasMaxLength(ProjectConsts.MaxDefaultDocumentNameLength);
b.Property(x => x.NavigationDocumentName).IsRequired().HasMaxLength(ProjectConsts.MaxNavigationDocumentNameLength);
b.Property(x => x.LatestVersionBranchName).HasMaxLength(ProjectConsts.MaxLatestVersionBranchNameLength);
b.ConfigureExtraProperties();
});
}
}

Loading…
Cancel
Save