[Abp vNext 源码分析] - 14. EntityFramework Core 的集成 (6)

首先看第一个项目的用法:

public abstract class RepositoryBase<TEntity> : BasicRepositoryBase<TEntity>, IRepository<TEntity> where TEntity : class, IEntity { public IDataFilter DataFilter { get; set; } // ... // 分别在查询的时候判断实体是否实现了两个接口。 protected virtual TQueryable ApplyDataFilters<TQueryable>(TQueryable query) where TQueryable : IQueryable<TEntity> { // 如果实现了软删除接口,则从 DataFilter 中获取过滤器的开启状态。 // 如果已经开启,则过滤掉被删除的数据。 if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) { query = (TQueryable)query.WhereIf(DataFilter.IsEnabled<ISoftDelete>(), e => ((ISoftDelete)e).IsDeleted == false); } // 如果实现了多租户接口,则从 DataFilter 中获取过滤器的开启状态。 // 如果已经开启,则按照租户 Id 过滤数据。 if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity))) { var tenantId = CurrentTenant.Id; query = (TQueryable)query.WhereIf(DataFilter.IsEnabled<IMultiTenant>(), e => ((IMultiTenant)e).TenantId == tenantId); } return query; } // ... }

逻辑比较简单,都是判断实体是否实现某个接口,并且结合启用状态来进行过滤,在原有 IQuerable 拼接 WhereIf() 即可。但是 EF Core 使用这种方式不行,所以上述方法只会在 Memory 和 MongoDb 有使用。

[Abp vNext 源码分析] - 14. EntityFramework Core 的集成

2.4.2 EF Core 的集成

EF Core 集成数据过滤器则是放在数据库上下文基类 AbpDbContext<TDbContext> 中,在数据库上下文的 OnModelCreating() 方法内通过 ConfigureBasePropertiesMethodInfo 进行反射调用。

public abstract class AbpDbContext<TDbContext> : DbContext, IEfCoreDbContext, ITransientDependency where TDbContext : DbContext { // ... protected virtual bool IsMultiTenantFilterEnabled => DataFilter?.IsEnabled<IMultiTenant>() ?? false; protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled<ISoftDelete>() ?? false; // ... public IDataFilter DataFilter { get; set; } // ... private static readonly MethodInfo ConfigureBasePropertiesMethodInfo = typeof(AbpDbContext<TDbContext>) .GetMethod( nameof(ConfigureBaseProperties), BindingFlags.Instance | BindingFlags.NonPublic ); // ... protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { ConfigureBasePropertiesMethodInfo .MakeGenericMethod(entityType.ClrType) .Invoke(this, new object[] { modelBuilder, entityType }); // ... } } // ... protected virtual void ConfigureBaseProperties<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) where TEntity : class { if (mutableEntityType.IsOwned()) { return; } ConfigureConcurrencyStampProperty<TEntity>(modelBuilder, mutableEntityType); ConfigureExtraProperties<TEntity>(modelBuilder, mutableEntityType); ConfigureAuditProperties<TEntity>(modelBuilder, mutableEntityType); ConfigureTenantIdProperty<TEntity>(modelBuilder, mutableEntityType); // 在这里,配置全局过滤器。 ConfigureGlobalFilters<TEntity>(modelBuilder, mutableEntityType); } // ... protected virtual void ConfigureGlobalFilters<TEntity>(ModelBuilder modelBuilder, IMutableEntityType mutableEntityType) where TEntity : class { // 符合条件则为其创建过滤表达式。 if (mutableEntityType.BaseType == null && ShouldFilterEntity<TEntity>(mutableEntityType)) { // 创建过滤表达式。 var filterExpression = CreateFilterExpression<TEntity>(); if (filterExpression != null) { // 为指定的实体配置查询过滤器。 modelBuilder.Entity<TEntity>().HasQueryFilter(filterExpression); } } } // ... // 判断实体是否拥有过滤器。 protected virtual bool ShouldFilterEntity<TEntity>(IMutableEntityType entityType) where TEntity : class { if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity))) { return true; } if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) { return true; } return false; } // 构建表达式。 protected virtual Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>() where TEntity : class { Expression<Func<TEntity, bool>> expression = null; if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) { expression = e => !IsSoftDeleteFilterEnabled || !EF.Property<bool>(e, "IsDeleted"); } if (typeof(IMultiTenant).IsAssignableFrom(typeof(TEntity))) { Expression<Func<TEntity, bool>> multiTenantFilter = e => !IsMultiTenantFilterEnabled || EF.Property<Guid>(e, "TenantId") == CurrentTenantId; expression = expression == null ? multiTenantFilter : CombineExpressions(expression, multiTenantFilter); } return expression; } // ... } 2.5 领域事件集成

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjzfw.html