Re-implementation of OrderBy, ThenBy and Null TypeMapping in Sql Tree error

c# entity-framework-core expression-trees lambda linq

Question

I'm attempting to implementOrderBy and ThenBy an alternative approach to conceal the lambda expressionOrderBy and ThenBy extension techniques The classes that implement these extension methods are accepted.IOrderSpecification :

public class PersonOrderByAgeSpecification : OrderSpecification<Person>
{
    public PersonOrderByAgeSpecification(Sort direction= Sort.Ascending) : base(direction)
    {
    }

    public override Expression<Func<Person, IComparable>> AsExpression()
    {
        return personOrder => personOrder.Age;
    }
}

The use is:

 var orderSpecification = new PersonOrderByAgeSpecification(Sort.Ascending); 
 var sortedPeople=  _dbContext.People.OrderBy(orderSpecification);

In the event that the property type isAsExpression() just string, For instance:

public override Expression<Func<Person, IComparable>> AsExpression()
{
    return personOrder => personOrder.FirstName;
}

I would then get the following error: (Does not work with integer or bool)

InvalidOperationException: Null TypeMapping in Sql Tree Microsoft.EntityFrameworkCore.Relational.Query.Pipeline.RelationalSqlTranslatingExpressionVisitor+SqlTypeMappingVerifyingExpressionVisitor.VisitExtension(Expression node)

Available source code is here.

Thank you for any assistance.

1
1
7/18/2019 8:15:02 AM

Accepted Answer

You are using preview (beta) software, which is first and foremost anticipated to have problems.

The second generic type parameter in LINQ ordering methods, however, is the primary issue.TKey , behind which you are obstructingIComparable which, for value types, results in an expression's hidden cast.

This is not an issue for the LINQ to Objects provider since it just compiles and runs a delegate from the lambda expression, apart from the needless boxing. though otherIQueryable Typically, service providers must change the phrase to something different (usually SQL). Most of them recognize these castings (Expression.Convert ) and eliminate them when processing. Your use of the EF 3.0 preview apparently does not, therefore the exception.

By removing the concealed casts yourself, you may steer clear of these problems. The simplest way to do it is to add the second generic type parameter to your basic abstract class, however expression manipulation is also an option:

public abstract class OrderSpecification<T, TKey> : IOrderSpecification<T>

the abstract method signature to, and

public abstract Expression<Func<T, TKey>> AsExpression();

Except for the actual classes, the implementation, interface, and everything else will stay the same.

All that's left to do is modify the inheriting class to indicate the actual key type.AsExpression replace the signature. For illustration:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

public class PersonAgeOrderSpecification : OrderSpecification<Person, int>
{
    public PersonAgeOrderSpecification(Sort direction) : base(direction) { }
    public override Expression<Func<Person, int>> AsExpression()
    {
        return person => person.Age;
    }
}

the situation will be OK.

2
7/18/2019 8:13:49 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow