-
-
Save dotnet22/edb34a5eb4e588b0217b8f7d8c968785 to your computer and use it in GitHub Desktop.
Revisions
-
haacked revised this gist
Mar 23, 2021 . 1 changed file with 8 additions and 19 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -51,40 +51,29 @@ static void SetQueryFilter<TEntity, TEntityInterface>( var concreteExpression = filterExpression .Convert<TEntityInterface, TEntity>(); builder.Entity<TEntity>() .AppendQueryFilter(concreteExpression); } // CREDIT: This comment by magiak on GitHub https://github.com/dotnet/efcore/issues/10275#issuecomment-785916356 static void AppendQueryFilter<T>(this EntityTypeBuilder entityTypeBuilder, Expression<Func<T, bool>> expression) where T : class { var parameterType = Expression.Parameter(entityTypeBuilder.Metadata.ClrType); var expressionFilter = ReplacingExpressionVisitor.Replace( expression.Parameters.Single(), parameterType, expression.Body); if (entityTypeBuilder.Metadata.GetQueryFilter() != null) { var currentQueryFilter = entityTypeBuilder.Metadata.GetQueryFilter(); var currentExpressionFilter = ReplacingExpressionVisitor.Replace( currentQueryFilter.Parameters.Single(), parameterType, currentQueryFilter.Body); expressionFilter = Expression.AndAlso(currentExpressionFilter, expressionFilter); } var lambdaExpression = Expression.Lambda(expressionFilter, parameterType); entityTypeBuilder.HasQueryFilter(lambdaExpression); } } public static class ExpressionExtensions -
haacked revised this gist
Aug 7, 2020 . 1 changed file with 4 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,7 @@ /* Copyright Phil Haack Licensed under the MIT license - https://github.com/haacked/CodeHaacks/blob/main/LICENSE. */ using System; using System.Linq; using System.Linq.Expressions; -
haacked revised this gist
Apr 30, 2020 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Query; public static class ModelBuilderExtensions { -
haacked revised this gist
Apr 30, 2020 . 1 changed file with 9 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,12 @@ using System; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Remotion.Linq.Parsing.ExpressionVisitors; public static class ModelBuilderExtensions { static readonly MethodInfo SetQueryFilterMethod = typeof(ModelBuilderExtensions) -
haacked revised this gist
Apr 30, 2020 . 1 changed file with 7 additions and 16 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,13 +1,3 @@ public static class ModelBuilderExtensions { static readonly MethodInfo SetQueryFilterMethod = typeof(ModelBuilderExtensions) @@ -23,7 +13,7 @@ public static void SetQueryFilterOnAllEntities<TEntityInterface>( .Select(t => t.ClrType) .Where(t => typeof(TEntityInterface).IsAssignableFrom(t))) { builder.SetEntityQueryFilter( type, filterExpression); } @@ -51,7 +41,7 @@ static void SetQueryFilter<TEntity, TEntityInterface>( .AddQueryFilter(concreteExpression); } // CREDIT: The AddQueryFilter and GetInternalEntityTypeBuilder methods come from this comment: // https://github.com/aspnet/EntityFrameworkCore/issues/10275#issuecomment-457504348 // And was written by https://github.com/YZahringer static void AddQueryFilter<T>(this EntityTypeBuilder entityTypeBuilder, Expression<Func<T, bool>> expression) @@ -61,19 +51,20 @@ static void AddQueryFilter<T>(this EntityTypeBuilder entityTypeBuilder, Expressi expression.Parameters.Single(), parameterType, expression.Body); var internalEntityTypeBuilder = entityTypeBuilder.GetInternalEntityTypeBuilder(); var queryFilter = internalEntityTypeBuilder?.Metadata.GetQueryFilter(); if (queryFilter != null) { var currentExpressionFilter = ReplacingExpressionVisitor.Replace( queryFilter.Parameters.Single(), parameterType, queryFilter.Body); expressionFilter = Expression.AndAlso(currentExpressionFilter, expressionFilter); } var lambdaExpression = Expression.Lambda(expressionFilter, parameterType); entityTypeBuilder.HasQueryFilter(lambdaExpression); } static InternalEntityTypeBuilder? GetInternalEntityTypeBuilder( this EntityTypeBuilder entityTypeBuilder) { var internalEntityTypeBuilder = typeof(EntityTypeBuilder) .GetProperty("Builder", BindingFlags.NonPublic | BindingFlags.Instance)? -
haacked revised this gist
Aug 20, 2019 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -51,6 +51,9 @@ static void SetQueryFilter<TEntity, TEntityInterface>( .AddQueryFilter(concreteExpression); } // The AddQueryFilter and GetInternalEntityTypeBuilder methods come from this comment: // https://github.com/aspnet/EntityFrameworkCore/issues/10275#issuecomment-457504348 // And was written by https://github.com/YZahringer static void AddQueryFilter<T>(this EntityTypeBuilder entityTypeBuilder, Expression<Func<T, bool>> expression) { var parameterType = Expression.Parameter(entityTypeBuilder.Metadata.ClrType); -
haacked revised this gist
Aug 20, 2019 . 1 changed file with 35 additions and 10 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,8 +1,12 @@ using System; using System.Collections.ObjectModel; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Remotion.Linq.Parsing.ExpressionVisitors; public static class ModelBuilderExtensions { @@ -44,16 +48,37 @@ static void SetQueryFilter<TEntity, TEntityInterface>( var concreteExpression = filterExpression .Convert<TEntityInterface, TEntity>(); builder.Entity<TEntity>() .AddQueryFilter(concreteExpression); } static void AddQueryFilter<T>(this EntityTypeBuilder entityTypeBuilder, Expression<Func<T, bool>> expression) { var parameterType = Expression.Parameter(entityTypeBuilder.Metadata.ClrType); var expressionFilter = ReplacingExpressionVisitor.Replace( expression.Parameters.Single(), parameterType, expression.Body); var internalEntityTypeBuilder = entityTypeBuilder.GetInternalEntityTypeBuilder(); if (internalEntityTypeBuilder.Metadata.QueryFilter != null) { var currentQueryFilter = internalEntityTypeBuilder.Metadata.QueryFilter; var currentExpressionFilter = ReplacingExpressionVisitor.Replace( currentQueryFilter.Parameters.Single(), parameterType, currentQueryFilter.Body); expressionFilter = Expression.AndAlso(currentExpressionFilter, expressionFilter); } var lambdaExpression = Expression.Lambda(expressionFilter, parameterType); entityTypeBuilder.HasQueryFilter(lambdaExpression); } static InternalEntityTypeBuilder GetInternalEntityTypeBuilder(this EntityTypeBuilder entityTypeBuilder) { var internalEntityTypeBuilder = typeof(EntityTypeBuilder) .GetProperty("Builder", BindingFlags.NonPublic | BindingFlags.Instance)? .GetValue(entityTypeBuilder) as InternalEntityTypeBuilder; return internalEntityTypeBuilder; } } public static class ExpressionExtensions { @@ -74,13 +99,13 @@ class ParameterTypeVisitor<TSource, TTarget> : ExpressionVisitor protected override Expression VisitParameter(ParameterExpression node) { return _parameters?.FirstOrDefault(p => p.Name == node.Name) ?? (node.Type == typeof(TSource) ? Expression.Parameter(typeof(TTarget), node.Name) : node); } protected override Expression VisitLambda<T>(Expression<T> node) { _parameters = VisitAndConvert(node.Parameters, "VisitLambda"); return Expression.Lambda(Visit(node.Body), _parameters); } } } -
haacked revised this gist
Jul 29, 2019 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,6 +15,7 @@ public static void SetQueryFilterOnAllEntities<TEntityInterface>( Expression<Func<TEntityInterface, bool>> filterExpression) { foreach (var type in builder.Model.GetEntityTypes() .Where(t => t.BaseType == null) .Select(t => t.ClrType) .Where(t => typeof(TEntityInterface).IsAssignableFrom(t))) { -
haacked created this gist
Jul 26, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,85 @@ using System; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Microsoft.EntityFrameworkCore; public static class ModelBuilderExtensions { static readonly MethodInfo SetQueryFilterMethod = typeof(ModelBuilderExtensions) .GetMethods(BindingFlags.NonPublic | BindingFlags.Static) .Single(t => t.IsGenericMethod && t.Name == nameof(SetQueryFilter)); public static void SetQueryFilterOnAllEntities<TEntityInterface>( this ModelBuilder builder, Expression<Func<TEntityInterface, bool>> filterExpression) { foreach (var type in builder.Model.GetEntityTypes() .Select(t => t.ClrType) .Where(t => typeof(TEntityInterface).IsAssignableFrom(t))) { builder.SetEntityQueryFilter<TEntityInterface>( type, filterExpression); } } static void SetEntityQueryFilter<TEntityInterface>( this ModelBuilder builder, Type entityType, Expression<Func<TEntityInterface, bool>> filterExpression) { SetQueryFilterMethod .MakeGenericMethod(entityType, typeof(TEntityInterface)) .Invoke(null, new object[] { builder, filterExpression }); } static void SetQueryFilter<TEntity, TEntityInterface>( this ModelBuilder builder, Expression<Func<TEntityInterface, bool>> filterExpression) where TEntityInterface : class where TEntity : class, TEntityInterface { var concreteExpression = filterExpression .Convert<TEntityInterface, TEntity>(); builder.Entity<TEntity>() .HasQueryFilter(concreteExpression); } } // ------------------------------------------------------- using System; using System.Collections.ObjectModel; using System.Linq; using System.Linq.Expressions; public static class ExpressionExtensions { // This magic is courtesy of this StackOverflow post. // https://stackoverflow.com/questions/38316519/replace-parameter-type-in-lambda-expression // I made some tweaks to adapt it to our needs - @haacked public static Expression<Func<TTarget, bool>> Convert<TSource, TTarget>( this Expression<Func<TSource, bool>> root) { var visitor = new ParameterTypeVisitor<TSource, TTarget>(); return (Expression<Func<TTarget, bool>>)visitor.Visit(root); } class ParameterTypeVisitor<TSource, TTarget> : ExpressionVisitor { private ReadOnlyCollection<ParameterExpression> _parameters; protected override Expression VisitParameter(ParameterExpression node) { return _parameters?.FirstOrDefault(p => p.Name == node.Name) ?? (node.Type == typeof(TSource) ? Expression.Parameter(typeof(TTarget), node.Name) : node); } protected override Expression VisitLambda<T>(Expression<T> node) { _parameters = VisitAndConvert<ParameterExpression>(node.Parameters, "VisitLambda"); return Expression.Lambda(Visit(node.Body), _parameters); } } }