diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/MySQL/AbpEntityFrameworkCoreMySQLModule.cs b/framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/MySQL/AbpEntityFrameworkCoreMySQLModule.cs index 6431590230..0b493f5058 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/MySQL/AbpEntityFrameworkCoreMySQLModule.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore.MySQL/Volo/Abp/EntityFrameworkCore/MySQL/AbpEntityFrameworkCoreMySQLModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Guids; +using Volo.Abp.EntityFrameworkCore.GlobalFilters; +using Volo.Abp.Guids; using Volo.Abp.Modularity; namespace Volo.Abp.EntityFrameworkCore.MySQL; @@ -17,5 +18,10 @@ public class AbpEntityFrameworkCoreMySQLModule : AbpModule options.DefaultSequentialGuidType = SequentialGuidType.SequentialAsString; } }); + + Configure(options => + { + options.UseDbFunction = true; + }); } } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart/Volo/Abp/EntityFrameworkCore/Oracle/Devart/AbpEntityFrameworkCoreOracleDevartModule.cs b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart/Volo/Abp/EntityFrameworkCore/Oracle/Devart/AbpEntityFrameworkCoreOracleDevartModule.cs index 3b4129b272..317f664b04 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart/Volo/Abp/EntityFrameworkCore/Oracle/Devart/AbpEntityFrameworkCoreOracleDevartModule.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle.Devart/Volo/Abp/EntityFrameworkCore/Oracle/Devart/AbpEntityFrameworkCoreOracleDevartModule.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.EntityFrameworkCore.GlobalFilters; using Volo.Abp.Guids; using Volo.Abp.Modularity; @@ -18,5 +19,10 @@ public class AbpEntityFrameworkCoreOracleDevartModule : AbpModule options.DefaultSequentialGuidType = SequentialGuidType.SequentialAsBinary; } }); + + Configure(options => + { + options.UseDbFunction = true; + }); } } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo/Abp/EntityFrameworkCore/Oracle/AbpEntityFrameworkCoreOracleModule.cs b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo/Abp/EntityFrameworkCore/Oracle/AbpEntityFrameworkCoreOracleModule.cs index 54627a90c0..76ffe32f7a 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo/Abp/EntityFrameworkCore/Oracle/AbpEntityFrameworkCoreOracleModule.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore.Oracle/Volo/Abp/EntityFrameworkCore/Oracle/AbpEntityFrameworkCoreOracleModule.cs @@ -1,4 +1,5 @@ using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.EntityFrameworkCore.GlobalFilters; using Volo.Abp.Guids; using Volo.Abp.Modularity; @@ -16,5 +17,10 @@ public class AbpEntityFrameworkCoreOracleModule : AbpModule options.DefaultSequentialGuidType = SequentialGuidType.SequentialAsBinary; } }); + + Configure(options => + { + options.UseDbFunction = true; + }); } } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/PostgreSql/AbpEntityFrameworkCorePostgreSqlModule.cs b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/PostgreSql/AbpEntityFrameworkCorePostgreSqlModule.cs index 2b679cccef..b82b128b3b 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/PostgreSql/AbpEntityFrameworkCorePostgreSqlModule.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo/Abp/EntityFrameworkCore/PostgreSql/AbpEntityFrameworkCorePostgreSqlModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Guids; +using Volo.Abp.EntityFrameworkCore.GlobalFilters; +using Volo.Abp.Guids; using Volo.Abp.Modularity; namespace Volo.Abp.EntityFrameworkCore.PostgreSql; @@ -17,5 +18,10 @@ public class AbpEntityFrameworkCorePostgreSqlModule : AbpModule options.DefaultSequentialGuidType = SequentialGuidType.SequentialAsString; } }); + + Configure(options => + { + options.UseDbFunction = true; + }); } } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo/Abp/EntityFrameworkCore/SqlServer/AbpEntityFrameworkCoreSqlServerModule.cs b/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo/Abp/EntityFrameworkCore/SqlServer/AbpEntityFrameworkCoreSqlServerModule.cs index 8186809846..acebc98d86 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo/Abp/EntityFrameworkCore/SqlServer/AbpEntityFrameworkCoreSqlServerModule.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore.SqlServer/Volo/Abp/EntityFrameworkCore/SqlServer/AbpEntityFrameworkCoreSqlServerModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Guids; +using Volo.Abp.EntityFrameworkCore.GlobalFilters; +using Volo.Abp.Guids; using Volo.Abp.Modularity; namespace Volo.Abp.EntityFrameworkCore.SqlServer; @@ -17,5 +18,10 @@ public class AbpEntityFrameworkCoreSqlServerModule : AbpModule options.DefaultSequentialGuidType = SequentialGuidType.SequentialAtEnd; } }); + + Configure(options => + { + options.UseDbFunction = true; + }); } } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo/Abp/EntityFrameworkCore/Sqlite/AbpEntityFrameworkCoreSqliteModule.cs b/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo/Abp/EntityFrameworkCore/Sqlite/AbpEntityFrameworkCoreSqliteModule.cs index e772546154..52415d73b1 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo/Abp/EntityFrameworkCore/Sqlite/AbpEntityFrameworkCoreSqliteModule.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore.Sqlite/Volo/Abp/EntityFrameworkCore/Sqlite/AbpEntityFrameworkCoreSqliteModule.cs @@ -1,3 +1,4 @@ +using Volo.Abp.EntityFrameworkCore.GlobalFilters; using Volo.Abp.Modularity; namespace Volo.Abp.EntityFrameworkCore.Sqlite; @@ -7,5 +8,11 @@ namespace Volo.Abp.EntityFrameworkCore.Sqlite; )] public class AbpEntityFrameworkCoreSqliteModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.UseDbFunction = true; + }); + } } 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 c1c87cdead..6f45b75dc3 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -103,9 +103,12 @@ public abstract class AbpDbContext : DbContext, IAbpEfCoreDbContext, BindingFlags.Instance | BindingFlags.NonPublic )!; + protected readonly DbContextOptions DbContextOptions; + protected AbpDbContext(DbContextOptions options) : base(options) { + DbContextOptions = options; } protected override void OnModelCreating(ModelBuilder modelBuilder) @@ -791,15 +794,14 @@ public abstract class AbpDbContext : DbContext, IAbpEfCoreDbContext, { Expression>? expression = null; - var abpEfCoreCurrentDbContext = this.GetService(); if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity))) { expression = e => !IsSoftDeleteFilterEnabled || !EF.Property(e, "IsDeleted"); - if (LazyServiceProvider != null && GlobalFilterOptions.Value.UseDbFunction) + if (LazyServiceProvider != null && GlobalFilterOptions.Value.UseDbFunction && DbContextOptions.FindExtension() != null) { expression = e => AbpEfCoreDataFilterDbFunctionMethods.SoftDeleteFilter(((ISoftDelete)e).IsDeleted, true); - modelBuilder.ConfigureSoftDeleteDbFunction(AbpEfCoreDataFilterDbFunctionMethods.SoftDeleteFilterMethodInfo, abpEfCoreCurrentDbContext); + modelBuilder.ConfigureSoftDeleteDbFunction(AbpEfCoreDataFilterDbFunctionMethods.SoftDeleteFilterMethodInfo, this.GetService()); } } @@ -807,10 +809,10 @@ public abstract class AbpDbContext : DbContext, IAbpEfCoreDbContext, { Expression> multiTenantFilter = e => !IsMultiTenantFilterEnabled || EF.Property(e, "TenantId") == CurrentTenantId; - if (LazyServiceProvider != null && GlobalFilterOptions.Value.UseDbFunction) + if (LazyServiceProvider != null && GlobalFilterOptions.Value.UseDbFunction && DbContextOptions.FindExtension() != null) { multiTenantFilter = e => AbpEfCoreDataFilterDbFunctionMethods.MultiTenantFilter(((IMultiTenant)e).TenantId, CurrentTenantId, true); - modelBuilder.ConfigureMultiTenantDbFunction(AbpEfCoreDataFilterDbFunctionMethods.MultiTenantFilterMethodInfo, abpEfCoreCurrentDbContext); + modelBuilder.ConfigureMultiTenantDbFunction(AbpEfCoreDataFilterDbFunctionMethods.MultiTenantFilterMethodInfo, this.GetService()); } expression = expression == null ? multiTenantFilter : QueryFilterExpressionHelper.CombineExpressions(expression, multiTenantFilter); diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/GlobalFilters/AbpEfCoreDataFilterDbFunctionMethods.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/GlobalFilters/AbpEfCoreDataFilterDbFunctionMethods.cs index e7d672e9ba..35694433ed 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/GlobalFilters/AbpEfCoreDataFilterDbFunctionMethods.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/GlobalFilters/AbpEfCoreDataFilterDbFunctionMethods.cs @@ -5,16 +5,20 @@ namespace Volo.Abp.EntityFrameworkCore.GlobalFilters; public static class AbpEfCoreDataFilterDbFunctionMethods { + private const string NotSupportedExceptionMessage = "Your EF Core database provider does not support 'User-defined function mapping'." + + "Please set 'UseDbFunction' of 'AbpEfCoreGlobalFilterOptions' to false to disable it." + + "See https://learn.microsoft.com/en-us/ef/core/querying/user-defined-function-mapping for more information." ; + public static bool SoftDeleteFilter(bool isDeleted, bool boolParam) { - throw new NotSupportedException("This method should be replaced by the database function call."); + throw new NotSupportedException(NotSupportedExceptionMessage); } public static MethodInfo SoftDeleteFilterMethodInfo => typeof(AbpEfCoreDataFilterDbFunctionMethods).GetMethod(nameof(SoftDeleteFilter))!; public static bool MultiTenantFilter(Guid? tenantId, Guid? currentTenantId, bool boolParam) { - throw new NotSupportedException("This method should be replaced by the database function call."); + throw new NotSupportedException(NotSupportedExceptionMessage); } public static MethodInfo MultiTenantFilterMethodInfo => typeof(AbpEfCoreDataFilterDbFunctionMethods).GetMethod(nameof(MultiTenantFilter))!; diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/GlobalFilters/AbpEfCoreGlobalFilterOptions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/GlobalFilters/AbpEfCoreGlobalFilterOptions.cs index 180ae849e7..e1641cd2a1 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/GlobalFilters/AbpEfCoreGlobalFilterOptions.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/GlobalFilters/AbpEfCoreGlobalFilterOptions.cs @@ -3,9 +3,4 @@ namespace Volo.Abp.EntityFrameworkCore.GlobalFilters; public class AbpEfCoreGlobalFilterOptions { public bool UseDbFunction { get; set; } - - public AbpEfCoreGlobalFilterOptions() - { - UseDbFunction = true; - } }