Base solution for your next web application
Open Closed

Additional Claims for Entity Filtering #11077


User avatar
0
rcasaca created
  • What is your product version? 11.0.0
  • What is your product type (Angular or MVC)? MVC
  • What is product framework type (.net framework or .net core)? .net core

I'm trying to add some custom data filtering in CreateFilterExpression method.

                Expression<Func<BookingEntity, bool>> entityTypes = e =>
                    e.Type == AccountAssociationType.Shipper
                    && ((e.AccountId == 4958 && e.Booking.AccountId == 2) || (e.AccountId == 4969 && e.Booking.AccountId == 3));

I've already built the condition using PredicateBuilder.

                Expression<Func<BookingEntity, bool>> entityTypesPredicate = PredicateBuilder.New<BookingEntity>(true);
                entityTypesPredicate = entityTypesPredicate.And(w => w.Type == AccountAssociationType.Shipper);
                Expression<Func<BookingEntity, bool>> predicateAssociations = PredicateBuilder.New<BookingEntity>(true);
                foreach (var a in AvailableContactAssociations)
                    predicateAssociations = predicateAssociations.Or(w => w.AccountId == a.Key && w.Booking.AccountId == a.Value);
                entityTypesPredicate = entityTypesPredicate.And(predicateAssociations);

Since entityTypesPredicate is built only when the application starts, how can use it every time I want to use it while building the FilterExpression? AvailableContactAssociations looks like: protected virtual List<ContactAssociation> AvailableContactAssociations

Any tip? What am I missing?

Thanks!


5 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    We are using a similar approach for TenantId. If you get the value of filter field using a method as exmpled here https://aspnetboilerplate.com/Pages/Documents/Articles\How-To\add-custom-data-filter-ef-core#configure-dbcontext, it will be executed every time when the filter is executed.

  • User Avatar
    0
    rcasaca created

    Hi ismcagdas,

    That's what I've foudn and implement in another usecase that I have in my solution. The question here is, the sql to built is a little more complex than have a List<int> and apply a .Contains on it. I have a List<int,int> and I need to apply them in a .Any filter. I can't find a solution to build it directly via lambda expressions so I was trying to use a PredicateBuilder and apply it.

    No luck yet. Any tip?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Have you tried something like this;

    Expression<Func<BookingEntity, bool>> entityTypesPredicate = GetEntityTypesFilterExpression();

    and move your code to GetEntityTypesFilterExpression method which you will create ?

  • User Avatar
    0
    rcasaca created

    To achieve that, i had to built my own CombineExpressions method.

    Expression<Func<T, bool>> CombineExpressions<T>(Expression<Func<T, bool>> expression1, Expression<Func<Booking, bool>> expression2)
    {
        var parameter = Expression.Parameter(typeof(T));
        var leftVisitor = new ReplaceExpressionVisitor(expression1.Parameters[0], parameter);
        var left = leftVisitor.Visit(expression1.Body);
        var rightVisitor = new ReplaceExpressionVisitor(expression2.Parameters[0], parameter);
        var right = rightVisitor.Visit(expression2.Body);
        return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(left, right), parameter);
    }
    

    Function GetBookingPredicate only runs when building the Context. It doesn't run each time I perform a query to db.

    protected Expression<Func<Booking, bool>> GetBookingPredicate()
    {
        Expression<Func<Booking, bool>> entityTypesPredicate = PredicateBuilder.New<Booking>(true);
    
        return entityTypesPredicate;
    }
    
    protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>()
    {
        var expression = base.CreateFilterExpression<TEntity>();
    
        if (typeof(IAmBooking).IsAssignableFrom(typeof(TEntity)))
        {
            Expression<Func<Booking, bool>> havePortFilter = GetBookingPredicate();
    
            expression = CombineExpressions(expression, havePortFilter);
        }
    }
    

    What am I missing? Thanks.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @rcasaca

    Is it possible to share your solution or a reproduction solution with us via email ([email protected]) ?