Search code examples
c#entity-frameworklinq-to-entitiesinterceptor

Entity Framework interceptor, default sorting


I'm trying to extend/copy this code by marisks

to include a default sorting interceptor. But for the life of me, I cannot wrap my head around the expressions and bindings.

Inspired by the SoftDelete code

var table = (EntityType)expression.Target.ElementType;
            if (table.Properties.All(p => p.Name != IsDeletedColumnName))
            {
                return base.Visit(expression);
            }

            var binding = expression.Bind();
            return binding.Filter(
                 binding.VariableType
                      .Variable(binding.VariableName)
                      .Property(IsDeletedColumnName)
                      .IsNull()
                );

I'm trying to add a similar thing to sort data be default. This is the closest I've come (that will compile)

var table = (EntityType)expression.Target.ElementType;
            string sortingColumn = "Priority";

            var binding = expression.Bind();

            return binding.Filter(
                 binding.VariableType
                      .Variable(binding.VariableName)
                      .Property(sortingColumn)
                      .OrderBy(m => m)
                );

but it throws an exception at runtime:

DbExpressionBinding requires an input expression with a collection ResultType. Parameter name: input

Can someone help me fix this - and possibly help me understand what's going on?


Solution

  • I did some hacking on my own. Basically the problem is that you try to create a Filter expression, but you need a Sort expression. Something like this:

    var sortingColumn = "OrderProp";
    var binding = expression.Bind();
    return DbExpressionBuilder.Sort(binding,
                    new[] {
                        DbExpressionBuilder.ToSortClause(binding.VariableType.Variable(binding.VariableName).Property(sortingColumn) )
                    });
    

    Of course, this only works, if you have the "OrderProp" on the type itself (you have to add extra checks for that).