zzzprojects / EntityFramework.DynamicFilters

Global filtering for Entity Framework.
https://entityframework-dynamicfilters.net/
MIT License
501 stars 87 forks source link

Create Filters with generic method #141

Closed lastreload closed 6 years ago

lastreload commented 6 years ago

using version:3.0.1 I'm trying to dinamically creating some filters.

This static filter works:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Filter("Unit_Cnfg_Filter",
                (UnitCnfg c) => (c.Agency.Code == Agency)
                && (c.Customer.Code == Customer)
                 && (c.Language.Code == Language)
            );
}

But creating a generic method that configure the same filter doesn't work:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{

      AddConfigFilter<UnitCnfg>(modelBuilder); 

}

...

        void AddConfigFilter<T>(DbModelBuilder modelBuilder)
            where T : IConfiguration
        {
            modelBuilder.Filter($"{typeof(T).Name}_filter", (T c) => ( c.Agency.Code == Agency)
                && ( c.Customer.Code == Customer)
                && ( c.Language.Code == Language));
        }

the filter seems to be added correctly, but when a query is executed it throw an exception:

"Unable to map parameter of type UnitCnfg to TypeUsage. Found 0 matching types"

Stack trace:

in EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.TypeUsageForPrimitiveType(Type type, ObjectContext objectContext, DataSpace dataSpace) in EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.CreateParameter(String name, Type type) in EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.GetDbExpressionForExpression(Expression expression) in EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitUnary(UnaryExpression node) in System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor) in System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) in System.Linq.Expressions.ExpressionVisitor.VisitMember(MemberExpression node) in EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitMember(MemberExpression node) in System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor) in System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) in System.Linq.Expressions.ExpressionVisitor.VisitMember(MemberExpression node) in EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitMember(MemberExpression node) in System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor) in System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) in System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node) in EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node) in System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor) in System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) in System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node) in EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node) in System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor) in System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) in System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node) in EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node) in System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor) in System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) in System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node) in EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.VisitBinary(BinaryExpression node) in System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor) in System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) in System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression1 node) in System.Linq.Expressions.Expression1.Accept(ExpressionVisitor visitor) in System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) in EntityFramework.DynamicFilters.LambdaToDbExpressionVisitor.Convert(DynamicFilterDefinition filter, DbExpressionBinding binding, DbContext dbContext, DataSpace dataSpace) in EntityFramework.DynamicFilters.DynamicFilterQueryVisitorCSpace.BuildFilterExpressionWithDynamicFilters(IEnumerable1 filterList, DbExpressionBinding binding, DbExpression predicate) in EntityFramework.DynamicFilters.DynamicFilterQueryVisitorCSpace.Visit(DbPropertyExpression expression) in System.Data.Entity.Core.Common.CommandTrees.DbPropertyExpression.Accept[TResultType](DbExpressionVisitor1 visitor) in System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression) in System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitList[TElement](IList1 list, Func2 map) in System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpressionList(IList1 list) in System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbNewInstanceExpression expression) in EntityFramework.DynamicFilters.DynamicFilterQueryVisitorCSpace.Visit(DbNewInstanceExpression expression) in System.Data.Entity.Core.Common.CommandTrees.DbNewInstanceExpression.Accept[TResultType](DbExpressionVisitor1 visitor) in System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.VisitExpression(DbExpression expression) in System.Data.Entity.Core.Common.CommandTrees.DefaultExpressionVisitor.Visit(DbProjectExpression expression) in EntityFramework.DynamicFilters.DynamicFilterQueryVisitorCSpace.Visit(DbProjectExpression expression) in System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor1 visitor) in EntityFramework.DynamicFilters.DynamicFilterInterceptor.TreeCreated(DbCommandTreeInterceptionContext interceptionContext) in System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.<Created>b__0(IDbCommandTreeInterceptor i, DbCommandTreeInterceptionContext c) in System.Data.Entity.Infrastructure.Interception.InternalDispatcher1.Dispatch[TInterceptionContext,TResult](TResult result, TInterceptionContext interceptionContext, Action`2 intercept) in System.Data.Entity.Infrastructure.Interception.DbCommandTreeDispatcher.Created(DbCommandTree commandTree, DbInterceptionContext interceptionContext) in System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext) in System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)

JonathanMagnan commented 6 years ago

Hello @lastreload ,

Do you think you could provide us a test project with this issue?

It will make easier/faster for my developer to getting started for investigating it.

We now always ask for a project since we found out that most issues are missing some essential information or are resolved by the requestor when creating it

(Even if the issue seem very easy to reproduce, by getting a test project, it allow us to give a faster support and better experience for the support of all our free libraries)

Best Regards,

Jonathan


Performance Libraries context.BulkInsert(list, options => options.BatchSize = 1000); Entity Framework ExtensionsBulk OperationsDapper PlusLinqToSql Plus

Runtime Evaluation Eval.Execute("x + y", new {x = 1, y = 2}); // return 3 C# Eval FunctionSQL Eval Function

lastreload commented 6 years ago

I hope this is the right way. Tanks for support.

IssueTestProject.zip

JonathanMagnan commented 6 years ago

Thank for the project,

One of my developers will be assigned to this issue.

Best Regards,

Jonathan

lastreload commented 6 years ago

I don't know why this code fail, but I understand that my code is useless. I don't need generate filters dinamically, your framework support interfaces so i can simply do something like this:

modelBuilder.Filter("UnitCnfg_Filter",
                    (IConfiguration c, string agency, string customer, string language) => (c.Agency.Code == Agency)
                    && (c.Customer.Code == Customer)
                     && (c.Language.Code == Language),(IssueContext ctx)=>ctx.Agency, (IssueContext ctx) =>ctx.Customer, (IssueContext ctx) =>ctx.Language
                );

and it works great!

JonathanMagnan commented 6 years ago

Oh that's even better ;)

Soon, we will have all our documentation online on .NET Fiddle (https://dotnetfiddle.net/), so it will be easier to getting started and find some online example. We are currently adding the support for Entity Framework and hope to have something available very soon.

Best Regards,

Jonathan