From 7ed94eb3a45ff141f0c7ea8fbec9a405e53ca2f2 Mon Sep 17 00:00:00 2001 From: tangdf Date: Tue, 16 Jan 2018 12:59:23 +0800 Subject: [PATCH] =?UTF-8?q?=20MulticastDelegate=20=20to=20Func?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/DelegateBenchmark/App.config | 45 ++ .../DelegateBenchmark.csproj | 160 ++++++ src/DelegateBenchmark/DelegateInvoking.cs | 42 ++ src/DelegateBenchmark/Program.cs | 14 + .../Properties/AssemblyInfo.cs | 36 ++ src/DelegateBenchmark/packages.config | 55 ++ src/EntityFramework.DynamicFilters.sln | 8 +- .../DynamicFilterExtensions.cs | 490 +++++++++--------- .../DynamicFilterParameters.cs | 9 +- .../EntityFramework.DynamicFilters.csproj | 4 +- 10 files changed, 602 insertions(+), 261 deletions(-) create mode 100644 src/DelegateBenchmark/App.config create mode 100644 src/DelegateBenchmark/DelegateBenchmark.csproj create mode 100644 src/DelegateBenchmark/DelegateInvoking.cs create mode 100644 src/DelegateBenchmark/Program.cs create mode 100644 src/DelegateBenchmark/Properties/AssemblyInfo.cs create mode 100644 src/DelegateBenchmark/packages.config diff --git a/src/DelegateBenchmark/App.config b/src/DelegateBenchmark/App.config new file mode 100644 index 0000000..d468254 --- /dev/null +++ b/src/DelegateBenchmark/App.config @@ -0,0 +1,45 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/DelegateBenchmark/DelegateBenchmark.csproj b/src/DelegateBenchmark/DelegateBenchmark.csproj new file mode 100644 index 0000000..d413af9 --- /dev/null +++ b/src/DelegateBenchmark/DelegateBenchmark.csproj @@ -0,0 +1,160 @@ + + + + + Debug + AnyCPU + {8262C3EC-B191-4E3F-915B-3BB4433310DE} + Exe + Properties + DelegateBenchmark + DelegateBenchmark + v4.6 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + ..\packages\BenchmarkDotNet.0.10.12\lib\net46\BenchmarkDotNet.dll + + + ..\packages\BenchmarkDotNet.Core.0.10.12\lib\net46\BenchmarkDotNet.Core.dll + + + ..\packages\BenchmarkDotNet.Toolchains.Roslyn.0.10.12\lib\net46\BenchmarkDotNet.Toolchains.Roslyn.dll + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + + + ..\packages\Microsoft.CodeAnalysis.Common.2.4.0\lib\netstandard1.3\Microsoft.CodeAnalysis.dll + + + ..\packages\Microsoft.CodeAnalysis.CSharp.2.4.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll + + + ..\packages\Microsoft.DotNet.InternalAbstractions.1.0.0\lib\net451\Microsoft.DotNet.InternalAbstractions.dll + + + ..\packages\Microsoft.DotNet.PlatformAbstractions.1.1.1\lib\net451\Microsoft.DotNet.PlatformAbstractions.dll + + + ..\packages\Microsoft.Win32.Registry.4.3.0\lib\net46\Microsoft.Win32.Registry.dll + + + + ..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll + True + + + ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + True + + + + + ..\packages\System.Console.4.3.0\lib\net46\System.Console.dll + + + + + ..\packages\System.Diagnostics.FileVersionInfo.4.3.0\lib\net46\System.Diagnostics.FileVersionInfo.dll + + + ..\packages\System.Diagnostics.StackTrace.4.3.0\lib\net46\System.Diagnostics.StackTrace.dll + + + ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll + True + + + ..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll + + + ..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll + + + + + ..\packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll + + + ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net46\System.Security.Cryptography.Algorithms.dll + True + + + ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + + + ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + + + ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net46\System.Security.Cryptography.X509Certificates.dll + True + + + ..\packages\System.Text.Encoding.CodePages.4.3.0\lib\net46\System.Text.Encoding.CodePages.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + + + ..\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll + + + ..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll + + + + + ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll + + + ..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll + + + ..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll + + + ..\packages\System.Xml.XPath.XDocument.4.3.0\lib\net46\System.Xml.XPath.XDocument.dll + + + + + + + + + + + Designer + + + + + + + + \ No newline at end of file diff --git a/src/DelegateBenchmark/DelegateInvoking.cs b/src/DelegateBenchmark/DelegateInvoking.cs new file mode 100644 index 0000000..8c7583c --- /dev/null +++ b/src/DelegateBenchmark/DelegateInvoking.cs @@ -0,0 +1,42 @@ +using System; +using System.Data.Entity; +using System.Linq; +using BenchmarkDotNet.Attributes; + +namespace DelegateBenchmark +{ + public class DelegateInvoking + { + private readonly MulticastDelegate _multicastDelegate; + + private readonly Func _funcDelegate; + + private readonly DbContext _dbContext; + + public DelegateInvoking() + { + Func condition = () => { return false; }; + + this._multicastDelegate = (MulticastDelegate) condition; + this._funcDelegate = (DbContext dbcontext) => { return condition(); }; + this._dbContext = new DbContext("default"); + } + + [Benchmark] + public bool MulticastDelegate_DynamicInvoke() + { + var func = this._multicastDelegate; + var parameters = func.Method.GetParameters(); + if (parameters.Any()) + return (bool) func.DynamicInvoke(_dbContext); + + return (bool) func.DynamicInvoke(); + } + + [Benchmark] + public bool FunDelegate_Invoke() + { + return this._funcDelegate.Invoke(this._dbContext); + } + } +} \ No newline at end of file diff --git a/src/DelegateBenchmark/Program.cs b/src/DelegateBenchmark/Program.cs new file mode 100644 index 0000000..199f5f4 --- /dev/null +++ b/src/DelegateBenchmark/Program.cs @@ -0,0 +1,14 @@ +using System; +using BenchmarkDotNet.Running; + +namespace DelegateBenchmark +{ + class Program + { + static void Main(string[] args) + { + BenchmarkRunner.Run(); + Console.ReadLine(); + } + } +} diff --git a/src/DelegateBenchmark/Properties/AssemblyInfo.cs b/src/DelegateBenchmark/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..40f6906 --- /dev/null +++ b/src/DelegateBenchmark/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("DelegateBenchmark")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("DelegateBenchmark")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("8262c3ec-b191-4e3f-915b-3bb4433310de")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/DelegateBenchmark/packages.config b/src/DelegateBenchmark/packages.config new file mode 100644 index 0000000..b77a3a1 --- /dev/null +++ b/src/DelegateBenchmark/packages.config @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/EntityFramework.DynamicFilters.sln b/src/EntityFramework.DynamicFilters.sln index ba581e0..15a390e 100644 --- a/src/EntityFramework.DynamicFilters.sln +++ b/src/EntityFramework.DynamicFilters.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.27004.2005 +VisualStudioVersion = 15.0.27130.2020 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EntityFramework.DynamicFilters", "EntityFramework.DynamicFilters\EntityFramework.DynamicFilters.csproj", "{56E36AD1-E675-42F0-96CB-7F475E05E491}" EndProject @@ -21,6 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Z.Lab", "Z.Lab\Z.Lab.csproj EndProject Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "Z.Lab.VB", "Z.Lab.VB\Z.Lab.VB.vbproj", "{6D24EDDC-96C8-495F-B1D2-0BFB74654173}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DelegateBenchmark", "DelegateBenchmark\DelegateBenchmark.csproj", "{8262C3EC-B191-4E3F-915B-3BB4433310DE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -47,6 +49,10 @@ Global {6D24EDDC-96C8-495F-B1D2-0BFB74654173}.Debug|Any CPU.Build.0 = Debug|Any CPU {6D24EDDC-96C8-495F-B1D2-0BFB74654173}.Release|Any CPU.ActiveCfg = Release|Any CPU {6D24EDDC-96C8-495F-B1D2-0BFB74654173}.Release|Any CPU.Build.0 = Release|Any CPU + {8262C3EC-B191-4E3F-915B-3BB4433310DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8262C3EC-B191-4E3F-915B-3BB4433310DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8262C3EC-B191-4E3F-915B-3BB4433310DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8262C3EC-B191-4E3F-915B-3BB4433310DE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/EntityFramework.DynamicFilters/DynamicFilterExtensions.cs b/src/EntityFramework.DynamicFilters/DynamicFilterExtensions.cs index 39305cd..88272a2 100644 --- a/src/EntityFramework.DynamicFilters/DynamicFilterExtensions.cs +++ b/src/EntityFramework.DynamicFilters/DynamicFilterExtensions.cs @@ -22,13 +22,15 @@ public static class DynamicFilterExtensions /// Key: Filter Name /// Value: The parameters for the filter /// - private static ConcurrentDictionary _GlobalParameterValues = new ConcurrentDictionary(); + private static ConcurrentDictionary _GlobalParameterValues = + new ConcurrentDictionary(); /// /// Key: The DbContext to which the scoped parameter values belong /// Values: A dictionary defined as _GlobalParameterValues that contains the scoped parameter values for the DbContext /// - private static ConcurrentDictionary> _ScopedParameterValues = new ConcurrentDictionary>(); + private static ConcurrentDictionary> _ScopedParameterValues = + new ConcurrentDictionary>(); /// /// These properties are used to prevent adding conditions to the sql queries to check to see if filters are @@ -88,9 +90,14 @@ public static void ResetDynamicFilters(this DbModelBuilder modelBuilder) /// If not null, specifies a globally scoped value for this parameter /// [Obsolete("Use modelBuilder.Filter() instead")] - public static EntityTypeConfiguration Filter(this EntityTypeConfiguration config, - string filterName, string columnName, object globalValue = null) - where TEntity : class + public static EntityTypeConfiguration Filter(this EntityTypeConfiguration config, string filterName, + string columnName, object globalValue = null) where TEntity : class + { + return EntityFilter(config, filterName, columnName, globalValue != null ? _ => globalValue : (Func) null); + } + + private static EntityTypeConfiguration EntityFilter(EntityTypeConfiguration config, string filterName, string columnName, + Func globalValue) where TEntity : class { filterName = ScrubFilterName(filterName); var filterDefinition = new DynamicFilterDefinition(Guid.NewGuid(), filterName, null, columnName, typeof(TEntity), null); @@ -119,31 +126,37 @@ public static EntityTypeConfiguration Filter(this EntityTypeCo /// #pragma warning disable 618 [Obsolete("Use modelBuilder.Filter() instead")] - public static EntityTypeConfiguration Filter(this EntityTypeConfiguration config, - string filterName, Expression> path, Func globalFuncValue = null) - where TEntity : class + public static EntityTypeConfiguration Filter(this EntityTypeConfiguration config, string filterName, + Expression> path, Func globalFuncValue = null) where TEntity : class { - return config.Filter(filterName, ParseColumnNameFromExpression(path), globalFuncValue); + return EntityFilter(config, filterName, ParseColumnNameFromExpression(path), _ => globalFuncValue?.Invoke()); } #endregion #region Single column equality only filter - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> path, Func globalFuncValue) - where TEntity : class + public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> path, + Func globalFuncValue) where TEntity : class { - modelBuilder.Filter(filterName, path, (object)globalFuncValue); + PrivateFilter(modelBuilder,filterName, path, _=> globalFuncValue?.Invoke()); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> path, Func globalFuncValue) - where TEntity : class - where TContext : DbContext + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> path, Func globalFuncValue) where TEntity : class where TContext : DbContext { - modelBuilder.Filter(filterName, path, (object)globalFuncValue); + PrivateFilter(modelBuilder,filterName, path, (DbContext dbContext) => globalFuncValue((TContext) dbContext)); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> path, object globalValue = null) + public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> path, + object globalValue = null) + { + PrivateFilter(modelBuilder, filterName, path, globalValue != null ? _ => globalValue : (Func) null); + } + + + private static void PrivateFilter(DbModelBuilder modelBuilder, string filterName, Expression> path, + Func globalValue) { InitializeDynamicFilters(null); @@ -179,11 +192,10 @@ public static void Filter(this DbModelBuilder modelBuilder, /// /// /// Options for how and when to apply this filter - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, Func value0, - Func options = null) - where TEntity : class + public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, + Func value0, Func options = null) where TEntity : class { - Filter(modelBuilder, filterName, options, predicate, (object)value0); + Filter(modelBuilder, filterName, options, predicate, _ => value0()); } /// @@ -197,12 +209,11 @@ public static void Filter(this DbModelBuilder modelBuilder, string /// /// /// Options for how and when to apply this filter - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, Func value0, - Func options = null) - where TEntity : class - where TContext : DbContext + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, Func value0, Func options = null) + where TEntity : class where TContext : DbContext { - Filter(modelBuilder, filterName, options, predicate, (object)value0); + Filter(modelBuilder, filterName, options, predicate, (DbContext context) => value0((TContext) context)); } /// @@ -215,106 +226,106 @@ public static void Filter(this DbModelBuilder modelBuilde /// /// /// Options for how and when to apply this filter - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, T0 value0, - Func options = null) - where TEntity : class + public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, + T0 value0, Func options = null) where TEntity : class { - Filter(modelBuilder, filterName, options, predicate, (object)value0); + Filter(modelBuilder, filterName, options, predicate, _ => value0); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - Func value0, Func value1, Func options = null) - where TEntity : class + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, Func value0, Func value1, + Func options = null) where TEntity : class { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1); + Filter(modelBuilder, filterName, options, predicate, _ => value0(), _ => value1()); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - Func value0, Func value1, Func options = null) - where TEntity : class - where TContext : DbContext + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, Func value0, Func value1, + Func options = null) where TEntity : class where TContext : DbContext { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1); + Filter(modelBuilder, filterName, options, predicate, (DbContext context) => value0((TContext) context), + (DbContext context) => value1((TContext) context)); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - T0 value0, T1 value1, Func options = null) + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, T0 value0, T1 value1, Func options = null) where TEntity : class { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1); + Filter(modelBuilder, filterName, options, predicate, _ => value0, _ => value1); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - Func value0, Func value1, Func value2, Func options = null) - where TEntity : class + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, Func value0, Func value1, Func value2, + Func options = null) where TEntity : class { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1, (object)value2); + Filter(modelBuilder, filterName, options, predicate, _ => value0(), _ => value1(), (DbContext context) => value2()); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - Func value0, Func value1, Func value2, - Func options = null) - where TEntity : class - where TContext : DbContext + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, Func value0, Func value1, Func value2, + Func options = null) where TEntity : class where TContext : DbContext { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1, (object)value2); + Filter(modelBuilder, filterName, options, predicate, (DbContext context) => value0((TContext) context), + (DbContext context) => value1((TContext) context), (DbContext context) => value2((TContext) context)); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - T0 value0, T1 value1, T2 value2, Func options = null) - where TEntity : class + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, T0 value0, T1 value1, T2 value2, + Func options = null) where TEntity : class { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1, (object)value2); + Filter(modelBuilder, filterName, options, predicate, _ => value0, _ => value1, _ => value2); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - Func value0, Func value1, Func value2, Func value3, Func options = null) - where TEntity : class + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, Func value0, Func value1, Func value2, Func value3, + Func options = null) where TEntity : class { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1, (object)value2, (object)value3); + Filter(modelBuilder, filterName, options, predicate, _ => value0(), _ => value1(), _ => value2(), _ => value3()); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - Func value0, Func value1, Func value2, Func value3, - Func options = null) - where TEntity : class - where TContext : DbContext + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, Func value0, Func value1, + Func value2, Func value3, Func options = null) + where TEntity : class where TContext : DbContext { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1, (object)value2, (object)value3); + Filter(modelBuilder, filterName, options, predicate, (DbContext context) => value0((TContext) context), + (DbContext context) => value1((TContext) context), (DbContext context) => value2((TContext) context), + (DbContext context) => value3((TContext) context)); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - T0 value0, T1 value1, T2 value2, T3 value3, Func options = null) - where TEntity : class + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, T0 value0, T1 value1, T2 value2, T3 value3, + Func options = null) where TEntity : class { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1, (object)value2, (object)value3); + Filter(modelBuilder, filterName, options, predicate, _ => value0, _ => value1, _ => value2, _ => value3); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - Func value0, Func value1, Func value2, Func value3, Func value4, - Func options = null) - where TEntity : class + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, Func value0, Func value1, Func value2, Func value3, + Func value4, Func options = null) where TEntity : class { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1, (object)value2, (object)value3, (object)value4); + Filter(modelBuilder, filterName, options, predicate, _ => value0(), _ => value1(), _ => value2(), _ => value3(), _ => value4()); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - Func value0, Func value1, Func value2, Func value3, Func value4, - Func options = null) - where TEntity : class - where TContext : DbContext + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, Func value0, Func value1, + Func value2, Func value3, Func value4, + Func options = null) where TEntity : class where TContext : DbContext { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1, (object)value2, (object)value3, (object)value4); + Filter(modelBuilder, filterName, options, predicate, (DbContext context) => value0((TContext) context), + (DbContext context) => value1((TContext) context), (DbContext context) => value2((TContext) context), + (DbContext context) => value3((TContext) context), (DbContext context) => value4((TContext) context)); } - public static void Filter(this DbModelBuilder modelBuilder, string filterName, Expression> predicate, - T0 value0, T1 value1, T2 value2, T3 value3, T4 value4, Func options = null) - where TEntity : class + public static void Filter(this DbModelBuilder modelBuilder, string filterName, + Expression> predicate, T0 value0, T1 value1, T2 value2, T3 value3, T4 value4, + Func options = null) where TEntity : class { - Filter(modelBuilder, filterName, options, predicate, (object)value0, (object)value1, (object)value2, (object)value3, (object)value4); + Filter(modelBuilder, filterName, options, predicate, _ => value0, _ => value1, _ => value2, _ => value3, _ => value4); } - private static void Filter(DbModelBuilder modelBuilder, string filterName, Func options, LambdaExpression predicate, params object[] valueList) + private static void Filter(DbModelBuilder modelBuilder, string filterName, Func options, + LambdaExpression predicate, params Func[] valueList) { InitializeDynamicFilters(null); @@ -327,9 +338,8 @@ private static void Filter(DbModelBuilder modelBuilder, string filterNa int numParams = predicate.Parameters == null ? 0 : predicate.Parameters.Count; int numValues = valueList == null ? 0 : valueList.Length; - for (int i = 1; i < numParams; i++) - { - object value = ((i - 1) < numValues) ? valueList[i - 1] : null; + for (int i = 1; i < numParams; i++) { + Func value = ((i - 1) < numValues) ? valueList[i - 1] : null; SetFilterGlobalParameterValue(null, filterName, predicate.Parameters[i].Name, value); } } @@ -372,7 +382,8 @@ public static void EnableFilter(this DbContext context, string filterName, Func< var filterParams = GetOrCreateScopedFilterParameters(context, filterName); filterParams.Enabled = true; - filterParams.EnableIfCondition = condition; + filterParams.EnableIfCondition = _ => (bool) condition(); + ; } /// @@ -391,7 +402,7 @@ public static void EnableFilter(this DbContext context, string filterN var filterParams = GetOrCreateScopedFilterParameters(context, filterName); filterParams.Enabled = true; - filterParams.EnableIfCondition = condition; + filterParams.EnableIfCondition = (DbContext dbContext) => (bool) condition((TContext)dbContext); } /// @@ -402,8 +413,7 @@ public static void EnableAllFilters(this DbContext context) { context.Database.Initialize(false); - foreach (var filterName in _GlobalParameterValues.Keys.ToList()) - { + foreach (var filterName in _GlobalParameterValues.Keys.ToList()) { if (AreFilterDisabledConditionsAllowed(filterName)) EnableFilter(context, filterName); } @@ -433,8 +443,7 @@ public static void DisableAllFilters(this DbContext context) { context.Database.Initialize(false); - foreach (var filterName in _GlobalParameterValues.Keys.ToList()) - { + foreach (var filterName in _GlobalParameterValues.Keys.ToList()) { if (AreFilterDisabledConditionsAllowed(filterName)) DisableFilter(context, filterName); } @@ -442,36 +451,34 @@ public static void DisableAllFilters(this DbContext context) public static void EnableFilter(this DbModelBuilder modelBuilder, string filterName, Func condition) { - EnableFilterGloballyIf(modelBuilder, filterName, condition as MulticastDelegate); + EnableFilterGloballyIf(modelBuilder, filterName, _ => condition()); } public static void EnableFilter(this DbModelBuilder modelBuilder, string filterName, Func condition) where TContext : DbContext { - EnableFilterGloballyIf(modelBuilder, filterName, condition as MulticastDelegate); + EnableFilterGloballyIf(modelBuilder, filterName, (DbContext dbContext) => condition((TContext)dbContext)); } - private static void EnableFilterGloballyIf(DbModelBuilder modelBuilder, string filterName, MulticastDelegate condition) + private static void EnableFilterGloballyIf(DbModelBuilder modelBuilder, string filterName, Func condition) { if (!AreFilterDisabledConditionsAllowed(filterName)) throw new ApplicationException("Enable/Disable filters conditions have been turned off via PreventDisabledFilterConditions!"); filterName = ScrubFilterName(filterName); - _GlobalParameterValues.AddOrUpdate(filterName, - (f) => - { - var newValues = new DynamicFilterParameters(); - newValues.Enabled = true; - newValues.EnableIfCondition = condition; - return newValues; - }, - (f, currValues) => - { - currValues.Enabled = true; - currValues.EnableIfCondition = condition; - return currValues; - }); + _GlobalParameterValues.AddOrUpdate(filterName, (f) => + { + var newValues = new DynamicFilterParameters(); + newValues.Enabled = true; + newValues.EnableIfCondition = condition; + return newValues; + }, (f, currValues) => + { + currValues.Enabled = true; + currValues.EnableIfCondition = condition; + return currValues; + }); } /// @@ -486,18 +493,16 @@ public static void DisableFilterGlobally(this DbModelBuilder modelBuilder, strin filterName = ScrubFilterName(filterName); - _GlobalParameterValues.AddOrUpdate(filterName, - (f) => - { - var newValues = new DynamicFilterParameters(); - newValues.Enabled = false; - return newValues; - }, - (f, currValues) => - { - currValues.Enabled = false; - return currValues; - }); + _GlobalParameterValues.AddOrUpdate(filterName, (f) => + { + var newValues = new DynamicFilterParameters(); + newValues.Enabled = false; + return newValues; + }, (f, currValues) => + { + currValues.Enabled = false; + return currValues; + }); } /// @@ -561,7 +566,7 @@ public static bool AreFilterDisabledConditionsAllowed(string filterName) /// the parameter value is needed. public static void SetFilterScopedParameterValue(this DbContext context, string filterName, Func func) { - context.SetFilterScopedParameterValue(filterName, null, (object)func); + context.SetFilterScopedParameterValue(filterName, null, (DbContext dbContext) => func?.Invoke()); } /// @@ -575,7 +580,7 @@ public static void SetFilterScopedParameterValue(this DbContext context, string public static void SetFilterScopedParameterValue(this DbContext context, string filterName, Func func) where TContext : DbContext { - context.SetFilterScopedParameterValue(filterName, null, (object)func); + context.SetFilterScopedParameterValue(filterName, null, (DbContext dbContext) => func?.Invoke((TContext) dbContext)); } /// @@ -600,7 +605,7 @@ public static void SetFilterScopedParameterValue(this DbContext context, string /// public static void SetFilterScopedParameterValue(this DbContext context, string filterName, string parameterName, Func func) { - context.SetFilterScopedParameterValue(filterName, parameterName, (object)func); + PrivateSetFilterScopedParameterValue(context, filterName, parameterName, _ => func?.Invoke()); } /// @@ -611,10 +616,10 @@ public static void SetFilterScopedParameterValue(this DbContext context, string /// /// /// - public static void SetFilterScopedParameterValue(this DbContext context, string filterName, string parameterName, Func func) - where TContext : DbContext + public static void SetFilterScopedParameterValue(this DbContext context, string filterName, string parameterName, + Func func) where TContext : DbContext { - context.SetFilterScopedParameterValue(filterName, parameterName, (object)func); + PrivateSetFilterScopedParameterValue(context, filterName, parameterName, (DbContext dbContext) => func?.Invoke((TContext)dbContext)); } /// @@ -626,6 +631,12 @@ public static void SetFilterScopedParameterValue(this DbContext contex /// /// public static void SetFilterScopedParameterValue(this DbContext context, string filterName, string parameterName, object value) + { + PrivateSetFilterScopedParameterValue(context, filterName, parameterName, _ => value); + } + + private static void PrivateSetFilterScopedParameterValue(this DbContext context, string filterName, string parameterName, + Func value) { context.Database.Initialize(false); @@ -636,7 +647,7 @@ public static void SetFilterScopedParameterValue(this DbContext context, string if (string.IsNullOrEmpty(parameterName)) parameterName = GetDefaultParameterNameForFilter(filterName); - DynamicFilterParameters globalFilterParams = _GlobalParameterValues[filterName]; // Already validated that this exists. + DynamicFilterParameters globalFilterParams = _GlobalParameterValues[filterName]; // Already validated that this exists. if (!globalFilterParams.ParameterValues.ContainsKey(parameterName)) throw new ApplicationException(string.Format("Parameter {0} not found in Filter {1}", parameterName, filterName)); @@ -657,7 +668,7 @@ public static void SetFilterScopedParameterValue(this DbContext context, string /// the parameter value is needed. public static void SetFilterGlobalParameterValue(this DbContext context, string filterName, Func func) { - context.SetFilterGlobalParameterValue(filterName, (object)func); + PrivateSetFilterGlobalParameterValue(context, filterName, null, _ => func?.Invoke()); } /// @@ -671,7 +682,7 @@ public static void SetFilterGlobalParameterValue(this DbContext context, string public static void SetFilterGlobalParameterValue(this DbContext context, string filterName, Func func) where TContext : DbContext { - context.SetFilterGlobalParameterValue(filterName, (object)func); + PrivateSetFilterGlobalParameterValue(context, filterName, null, (DbContext dbContext) => func?.Invoke((TContext)dbContext)); } /// @@ -683,21 +694,28 @@ public static void SetFilterGlobalParameterValue(this DbContext contex /// public static void SetFilterGlobalParameterValue(this DbContext context, string filterName, object value) { - context.SetFilterGlobalParameterValue(filterName, null, value); + PrivateSetFilterGlobalParameterValue(context, filterName, null, _ => value); } public static void SetFilterGlobalParameterValue(this DbContext context, string filterName, string parameterName, Func func) { - context.SetFilterGlobalParameterValue(filterName, parameterName, (object)func); + PrivateSetFilterGlobalParameterValue(context, filterName, parameterName, _ => func?.Invoke()); } - public static void SetFilterGlobalParameterValue(this DbContext context, string filterName, string parameterName, Func func) - where TContext : DbContext + public static void SetFilterGlobalParameterValue(this DbContext context, string filterName, string parameterName, + Func func) where TContext : DbContext { - context.SetFilterGlobalParameterValue(filterName, parameterName, (object)func); + PrivateSetFilterGlobalParameterValue(context, filterName, parameterName, (DbContext dbContext) => func?.Invoke((TContext)dbContext)); } public static void SetFilterGlobalParameterValue(this DbContext context, string filterName, string parameterName, object value) + { + PrivateSetFilterGlobalParameterValue(context, filterName, parameterName, _ => value); + } + + + private static void PrivateSetFilterGlobalParameterValue(this DbContext context, string filterName, string parameterName, + Func value) { // This is null when called during filter creation in OnModelCreating if (context != null) @@ -708,18 +726,16 @@ public static void SetFilterGlobalParameterValue(this DbContext context, string if (string.IsNullOrEmpty(parameterName)) parameterName = GetDefaultParameterNameForFilter(filterName); - _GlobalParameterValues.AddOrUpdate(filterName, - (f) => - { - var newValues = new DynamicFilterParameters(); - newValues.SetParameter(parameterName, value); - return newValues; - }, - (f, currValues) => - { - currValues.SetParameter(parameterName, value); - return currValues; - }); + _GlobalParameterValues.AddOrUpdate(filterName, (f) => + { + var newValues = new DynamicFilterParameters(); + newValues.SetParameter(parameterName, value); + return newValues; + }, (f, currValues) => + { + currValues.SetParameter(parameterName, value); + return currValues; + }); } #endregion @@ -756,7 +772,7 @@ public static object GetFilterParameterValue(this DbContext context, string filt // First check to see if this the Disabled parameter. if (parameterName == DynamicFilterConstants.FILTER_DISABLED_NAME) - return context.IsFilterEnabled(filterName) ? null : (object)true; + return context.IsFilterEnabled(filterName) ? null : (object) true; filterName = ScrubFilterName(filterName); if (parameterName == null) @@ -764,41 +780,26 @@ public static object GetFilterParameterValue(this DbContext context, string filt ConcurrentDictionary contextFilters; DynamicFilterParameters filterParams; - object value; + Func parameterValueFunc; // First try to get the value from _ScopedParameterValues - if (_ScopedParameterValues.TryGetValue(context, out contextFilters)) - { - if (contextFilters.TryGetValue(filterName, out filterParams)) - { - if (filterParams.ParameterValues.TryGetValue(parameterName, out value)) - return EvaluateValue(value, context); + if (_ScopedParameterValues.TryGetValue(context, out contextFilters)) { + if (contextFilters.TryGetValue(filterName, out filterParams)) { + if (filterParams.ParameterValues.TryGetValue(parameterName, out parameterValueFunc)) + return parameterValueFunc(context); } } // Then try _GlobalParameterValues - if (_GlobalParameterValues.TryGetValue(filterName, out filterParams)) - { - if (filterParams.ParameterValues.TryGetValue(parameterName, out value)) - return EvaluateValue(value, context); + if (_GlobalParameterValues.TryGetValue(filterName, out filterParams)) { + if (filterParams.ParameterValues.TryGetValue(parameterName, out parameterValueFunc)) + return parameterValueFunc(context); } // Not found anywhere??? return null; } - private static object EvaluateValue(object value, DbContext context) - { - var func = value as MulticastDelegate; - if (func == null) - return value; - - var parameters = func.Method.GetParameters(); - if (parameters.Any()) - return func.DynamicInvoke(context); - - return func.DynamicInvoke(); - } /// /// Checks to see if the filter is currently enabled based on the DbContext or global settings. @@ -816,15 +817,12 @@ public static bool IsFilterEnabled(this DbContext context, string filterName) DynamicFilterParameters filterParams; // If specifically enabled/disabled on local scope, that overrides anything global - if (_ScopedParameterValues.TryGetValue(context, out contextFilters)) - { - if (contextFilters.TryGetValue(filterName, out filterParams)) - { - if (filterParams.Enabled.HasValue) - { + if (_ScopedParameterValues.TryGetValue(context, out contextFilters)) { + if (contextFilters.TryGetValue(filterName, out filterParams)) { + if (filterParams.Enabled.HasValue) { // If the filter is enabled and it has an EnableIfCondition, evaluate it and return that bool value. if (filterParams.Enabled.Value && (filterParams.EnableIfCondition != null)) - return (bool)EvaluateValue(filterParams.EnableIfCondition, context); + return filterParams.EnableIfCondition(context); return filterParams.Enabled.Value; } @@ -832,13 +830,11 @@ public static bool IsFilterEnabled(this DbContext context, string filterName) } // Otherwise, we look to the global Enabled flag. - if (_GlobalParameterValues.TryGetValue(filterName, out filterParams)) - { - if (filterParams.Enabled.HasValue) - { + if (_GlobalParameterValues.TryGetValue(filterName, out filterParams)) { + if (filterParams.Enabled.HasValue) { // If the filter is enabled and it has an EnableIfCondition, evaluate it and return that bool value. if (filterParams.Enabled.Value && (filterParams.EnableIfCondition != null)) - return (bool)EvaluateValue(filterParams.EnableIfCondition, context); + return filterParams.EnableIfCondition(context); return filterParams.Enabled.Value; } @@ -870,13 +866,12 @@ public static void ClearScopedParameters(this DbContext context) internal static void SetSqlParameters(this DbContext context, DbCommand command) { - foreach (DbParameter param in command.Parameters) - { + foreach (DbParameter param in command.Parameters) { // Item1 = Filter Name // Item2 = Parameter/Column Name var filterNameAndParam = DynamicFilterDefinition.GetFilterAndParamFromDBParameter(param.ParameterName); if (filterNameAndParam == null) - continue; // Not dynamic filter param + continue; // Not dynamic filter param // Changing from SSpace -> CSpace also caused param.Value to be set to "null" instead of DBNull! // Must do this in case we don't set anything below (which will happen if param is an empty Enumerable). @@ -886,10 +881,9 @@ internal static void SetSqlParameters(this DbContext context, DbCommand command) // If not found, set to DBNull. It should already be set to that, but it's not in Postgre and we get // errors if we don't do that now. - if (value == null) - { - if ((filterNameAndParam.Item2 == DynamicFilterConstants.FILTER_DISABLED_NAME) && CanRemoveFilterDisabledConditionFromQuery(context)) - { + if (value == null) { + if ((filterNameAndParam.Item2 == DynamicFilterConstants.FILTER_DISABLED_NAME) + && CanRemoveFilterDisabledConditionFromQuery(context)) { // This is the "is disabled" param and the filter is not disabled. There are cases where // including the "OR (@DynamicFilterParam_1 IS NOT NULL)" clause causes problems with // SQL Server index usage (it may decide not to use a multi-column index where the first @@ -900,24 +894,26 @@ internal static void SetSqlParameters(this DbContext context, DbCommand command) RemoveFilterDisabledConditionFromQuery(command, param); #if (DEBUG) - if (!string.IsNullOrEmpty(command.CommandText) && command.CommandText.ToLower().Contains(param.ParameterName + " is not null")) - throw new ApplicationException(string.Format("CommandText still contains ParameterName {0} after RemoveFilterDisabledConditionFromQuery", param.ParameterName)); + if (!string.IsNullOrEmpty(command.CommandText) + && command.CommandText.ToLower().Contains(param.ParameterName + " is not null")) + throw new ApplicationException(string.Format( + "CommandText still contains ParameterName {0} after RemoveFilterDisabledConditionFromQuery", param.ParameterName)); #endif } + param.Value = DBNull.Value; } - else - { + else { // Check to see if it's a collection. If so, this is an "In" parameter var valueType = value.GetType(); - if (valueType.IsGenericType && typeof(IEnumerable).IsAssignableFrom(valueType)) - { + if (valueType.IsGenericType && typeof(IEnumerable).IsAssignableFrom(valueType)) { // Generic collection. The EF query created for this collection was an '=' condition. // We need to convert this into an 'in' clause so that we can dynamically set the // values in the collection. SetParameterList(value as IEnumerable, param, command, context); if (context.Database.Log != null) - context.Database.Log(string.Format("Manually replaced single parameter value with list, new SQL=\r\n{0}", command.CommandText)); + context.Database.Log(string.Format("Manually replaced single parameter value with list, new SQL=\r\n{0}", + command.CommandText)); } else param.Value = value; @@ -934,19 +930,16 @@ private static void RemoveFilterDisabledConditionFromQuery(DbCommand command, Db int paramIdx; // Must include the "IS NOT NULL" part here. When switched to using CSpace, the SQL was slightly different // and found a case (covered by test case "AccountAndBlogEntries") where an embedded select was returning these parameters! - while ((paramIdx = command.CommandText.IndexOf(param.ParameterName + " IS NOT NULL", StringComparison.CurrentCultureIgnoreCase)) != -1) - { + while ((paramIdx = command.CommandText.IndexOf(param.ParameterName + " IS NOT NULL", StringComparison.CurrentCultureIgnoreCase)) != -1) { int startIdx = command.CommandText.LastIndexOf("or", paramIdx, StringComparison.CurrentCultureIgnoreCase); int endIdx = command.CommandText.IndexOf(")", paramIdx); - if (endIdx == -1) - { + if (endIdx == -1) { // PostgreSQL does not wrap all conditions in () (see below for example) so we may not find this. // So assume end of line. endIdx = command.CommandText.Length - 1; } - else - { + else { // PostgreSQL formats the sql like this: ("Var_1"."ID" < @DynamicFilterParam_000001 OR @DynamicFilterParam_000002 IS NOT NULL) // While other DBs format like this: (("Var_1"."ID" < @DynamicFilterParam_000001) OR (@DynamicFilterParam_000002 IS NOT NULL)) // (note the extra ()'s which are not present in PostgreSQL). @@ -954,13 +947,13 @@ private static void RemoveFilterDisabledConditionFromQuery(DbCommand command, Db // Determine that by checking for the presence of an opening "(" in between the "or" and the parameter name var openingParenIndex = command.CommandText.IndexOf("(", startIdx); if ((openingParenIndex < startIdx) || (openingParenIndex > paramIdx)) - endIdx--; // Do not have opening paren so do not remove the trailing ")"! + endIdx--; // Do not have opening paren so do not remove the trailing ")"! } - if ((startIdx < 0) || (endIdx < 0)) - { + if ((startIdx < 0) || (endIdx < 0)) { #if (DEBUG) - throw new ApplicationException(string.Format("Failed to find start or end index of remove filter clause for parameter name {0}", param.ParameterName)); + throw new ApplicationException(string.Format("Failed to find start or end index of remove filter clause for parameter name {0}", + param.ParameterName)); #else return; #endif @@ -987,11 +980,9 @@ private static void SetParameterList(IEnumerable paramValueCollection, DbParamet int prevStartIndex = 0; int paramStartIdx; bool isNotCondition = false; - while ((paramStartIdx = command.CommandText.IndexOf(param.ParameterName, prevStartIndex)) != -1) - { + while ((paramStartIdx = command.CommandText.IndexOf(param.ParameterName, prevStartIndex)) != -1) { int startIdx = FindLastComparisonOperator(command.CommandText, paramStartIdx, out isNotCondition); - if (startIdx == -1) - { + if (startIdx == -1) { // EF sometimes includes our parameter values in sub-queries (as of the change to CSpace)! // So if we don't find a valid comparison immediately before the parameter reference, just skip past it. prevStartIndex = paramStartIdx + param.ParameterName.Length; @@ -1006,23 +997,19 @@ private static void SetParameterList(IEnumerable paramValueCollection, DbParamet inCondition.Append(param.ParameterName); bool isFirst = true; - foreach (var singleValue in paramValueCollection) - { + foreach (var singleValue in paramValueCollection) { object value = singleValue; - if (singleValue != null) - { + if (singleValue != null) { // If this is an Enum, need to cast it to an int if (singleValue.GetType().IsEnum) - value = (int)singleValue; + value = (int) singleValue; } - if (isFirst) - { + if (isFirst) { // The first item in the list is set as the value of the sql parameter param.Value = value; } - else - { + else { // Remaining valus must be inserted directly into the sql 'in' clause inCondition.AppendFormat(", {0}", QuotedValue(param, value, isOracle, isMySql)); } @@ -1033,11 +1020,11 @@ private static void SetParameterList(IEnumerable paramValueCollection, DbParamet inCondition.Append(")"); if (!canChangeCommandText) - throw new ApplicationException("This Database Provider does not support modifing the DbCommand.CommandText property - IEnumerable values cannot be set"); + throw new ApplicationException( + "This Database Provider does not support modifing the DbCommand.CommandText property - IEnumerable values cannot be set"); - command.CommandText = string.Concat(command.CommandText.Substring(0, startIdx), - inCondition, - command.CommandText.Substring(paramStartIdx + param.ParameterName.Length)); + command.CommandText = string.Concat(command.CommandText.Substring(0, startIdx), inCondition, + command.CommandText.Substring(paramStartIdx + param.ParameterName.Length)); prevStartIndex = startIdx + inCondition.Length; } @@ -1054,7 +1041,7 @@ private static int FindLastComparisonOperator(string commandText, int fromIdx, o notEqualIdx = commandText.LastIndexOf("<>", fromIdx, 10); int equalIdx = commandText.LastIndexOf("=", fromIdx, 10); - if (equalIdx == notEqualIdx + 1) // Don't want to match on the "=" in "!=" + if (equalIdx == notEqualIdx + 1) // Don't want to match on the "=" in "!=" equalIdx = -1; isNotCondition = notEqualIdx > equalIdx; @@ -1067,23 +1054,22 @@ private static string QuotedValue(DbParameter param, object value, bool isOracle return "null"; if (value is bool) - return (bool)value ? "1" : "0"; + return (bool) value ? "1" : "0"; - if (value is DateTime) - { + if (value is DateTime) { string d; if (isMySql) - d = string.Format("'{0:yyyy-MM-dd HH:mm:ss}'", (DateTime)value); // MySql does not support milliseconds and will fail to match if we include it + d = string.Format("'{0:yyyy-MM-dd HH:mm:ss}'", + (DateTime) value); // MySql does not support milliseconds and will fail to match if we include it else - d = string.Format("'{0:yyyy-MM-dd HH:mm:ss.fff}'", (DateTime)value); + d = string.Format("'{0:yyyy-MM-dd HH:mm:ss.fff}'", (DateTime) value); if (isOracle) return string.Format("to_date({0}, 'YYYY-MM-DD HH24:MI:SS.FF3')", d); return d; } - if (value is DateTimeOffset) - { - var d = string.Format("'{0:yyyy-MM-dd HH:mm:ss.fff K}'", (DateTimeOffset)value); + if (value is DateTimeOffset) { + var d = string.Format("'{0:yyyy-MM-dd HH:mm:ss.fff K}'", (DateTimeOffset) value); if (isOracle) return string.Format("to_timestamp_tz({0}, 'YYYY-MM-DD HH24:MI:SS.FF3 TZH:TZM')", d); return d; @@ -1092,11 +1078,10 @@ private static string QuotedValue(DbParameter param, object value, bool isOracle if (DbTypeIsNumeric(param.DbType)) return value.ToString(); - if (isOracle && (value is Guid)) - { + if (isOracle && (value is Guid)) { // In Oracle, a Guid is stored as RAW(16). So need to convert the Guid into a byte[] and // the use the hextoraw function to convert it from a hex string to raw. - string hex = BitConverter.ToString(((Guid)value).ToByteArray()).Replace("-", "").ToLower(); + string hex = BitConverter.ToString(((Guid) value).ToByteArray()).Replace("-", "").ToLower(); return string.Format("hextoraw('{0}')", hex); } @@ -1105,8 +1090,7 @@ private static string QuotedValue(DbParameter param, object value, bool isOracle private static bool DbTypeIsNumeric(DbType dbType) { - switch (dbType) - { + switch (dbType) { case DbType.Byte: case DbType.Currency: case DbType.Decimal: @@ -1150,7 +1134,8 @@ public static Version OracleVersion(this DbContext context) return _OracleInstanceVersions.GetOrAdd(context.Database.Connection.ConnectionString, k => { - var versionStr = context.Database.SqlQuery("select version from product_component_version where product like '%Database%'").FirstOrDefault(); + var versionStr = context.Database.SqlQuery("select version from product_component_version where product like '%Database%'") + .FirstOrDefault(); return new Version(string.Join(".", versionStr.Split('.').Take(4))); }); @@ -1220,18 +1205,16 @@ private static DynamicFilterParameters GetOrCreateScopedFilterParameters(DbConte var contextFilters = _ScopedParameterValues.GetOrAdd(context, newContextFilters); var filterParams = contextFilters.GetOrAdd(filterName, (p) => new DynamicFilterParameters()); - if (contextFilters == newContextFilters) - { + if (contextFilters == newContextFilters) { System.Diagnostics.Debug.Print("Created new scoped filter params. Have {0} scopes", _ScopedParameterValues.Count); // We created new filter params for this scope. Add an event handler to the OnDispose to clean them up when // the context is disposed. - var internalContext = typeof(DbContext) - .GetProperty("InternalContext", BindingFlags.Instance | BindingFlags.NonPublic) - .GetGetMethod(true) - .Invoke(context, null); + var internalContext = typeof(DbContext).GetProperty("InternalContext", BindingFlags.Instance | BindingFlags.NonPublic) + .GetGetMethod(true).Invoke(context, null); - var eventInfo = internalContext.GetType().GetEvent("OnDisposing", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); + var eventInfo = internalContext.GetType() + .GetEvent("OnDisposing", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); eventInfo.AddEventHandler(internalContext, new EventHandler((o, e) => context.ClearScopedParameters())); } @@ -1250,7 +1233,8 @@ private static string GetDefaultParameterNameForFilter(string filterName) throw new ApplicationException(string.Format("Filter name {0} not found", filterName)); if (globalFilterParams.ParameterValues.Count != 1) - throw new ApplicationException("Attempted to set Scoped Parameter without specifying Parameter Name and when filter does not contain exactly 1 parameter"); + throw new ApplicationException( + "Attempted to set Scoped Parameter without specifying Parameter Name and when filter does not contain exactly 1 parameter"); return globalFilterParams.ParameterValues.Keys.FirstOrDefault(); } @@ -1261,16 +1245,14 @@ private static string ParseColumnNameFromExpression(LambdaExpression expression) throw new ArgumentNullException("Lambda expression is null"); var body = expression.Body as MemberExpression; - if ((body == null) || (body.Member == null) || string.IsNullOrEmpty(body.Member.Name)) - { + if ((body == null) || (body.Member == null) || string.IsNullOrEmpty(body.Member.Name)) { // The expression does not specify a column - it's a lambda expression/predicate that will need to // be expanded by LabdaToDbExprssionVisitor during the query evaluation. return null; } var propertyExpression = body.Expression as MemberExpression; - if ((propertyExpression != null) && (propertyExpression.Member != null) && (propertyExpression.Member.Name != body.Member.Name)) - { + if ((propertyExpression != null) && (propertyExpression.Member != null) && (propertyExpression.Member.Name != body.Member.Name)) { // The expression is a property accessor - i.e. field.HasValue. It's a lambda expression/predicate return null; } diff --git a/src/EntityFramework.DynamicFilters/DynamicFilterParameters.cs b/src/EntityFramework.DynamicFilters/DynamicFilterParameters.cs index a5c4fcd..c507dae 100644 --- a/src/EntityFramework.DynamicFilters/DynamicFilterParameters.cs +++ b/src/EntityFramework.DynamicFilters/DynamicFilterParameters.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Data.Entity; using System.Linq; using System.Text; @@ -17,16 +18,16 @@ public class DynamicFilterParameters /// Can (optionally) take a single parameter for the current DbContext instance. /// Only evaluated if not null and if Enabled == true. /// - public MulticastDelegate EnableIfCondition { get; set; } + public Func EnableIfCondition { get; set; } - public ConcurrentDictionary ParameterValues { get; private set; } + public ConcurrentDictionary> ParameterValues { get; private set; } public DynamicFilterParameters() { - ParameterValues = new ConcurrentDictionary(); + ParameterValues = new ConcurrentDictionary>(); } - public void SetParameter(string parameterName, object value) + public void SetParameter(string parameterName, Func value) { ParameterValues.AddOrUpdate(parameterName, value, (k, v) => value); } diff --git a/src/EntityFramework.DynamicFilters/EntityFramework.DynamicFilters.csproj b/src/EntityFramework.DynamicFilters/EntityFramework.DynamicFilters.csproj index 0cf4075..35053be 100644 --- a/src/EntityFramework.DynamicFilters/EntityFramework.DynamicFilters.csproj +++ b/src/EntityFramework.DynamicFilters/EntityFramework.DynamicFilters.csproj @@ -36,7 +36,8 @@ true - zzzproject.pfx + + @@ -72,7 +73,6 @@ -