christo
christo

Reputation: 701

Entity Framework not support expression trees

I try sort my queryable collection with custom expression:

.Lambda #Lambda1<System.Func`2[MyProject.Client,System.Object]>(MyProject.Client $var1)
{
    .Block() {
        .If ($var1.Legal == null) {
            .Return #Label1 { (System.Object)($var1.Person).Email }
        } .Else {
            .Return #Label1 { (System.Object)($var1.Legal).Email }
        };
        .Label
            .Constant<System.Object>(System.Object)
        .LabelTarget #Label1:
    }
}

However, when attempting cast my collection to list application throws exception:

An exception of type 'System.NotSupportedException' occurred in EntityFramework.SqlServer.dll but was not handled in user code

Additional information: Unknown LINQ expression of type 'Block'.

UPD to Stilgar

I use conditional expression. My sort extension:

public static IOrderedQueryable<TSource> SortMultipleField<TSource>(this IQueryable<TSource> source, string propNames, bool ascending)
{
    var type = typeof(TSource);
    var param = Expression.Parameter(type);

    var sortFields = propNames.Split(',');

    Expression firstParent = param;
    var firstFieldPath = sortFields[0].Split('.');
    foreach (var item in firstFieldPath)
        firstParent = Expression.Property(firstParent, item);
    firstParent = Expression.Convert(firstParent, typeof(object));

    Expression secondParent = param;
    foreach (var item in sortFields[1].Split('.'))
        secondParent = Expression.Property(secondParent, item);
    secondParent = Expression.Convert(secondParent, typeof(object));

    var check = Expression.Property(param, firstFieldPath[0]);
    var checkNullExpression = Expression.Equal(check, Expression.Constant(null, check.Type));
    var returnTarget = Expression.Label(typeof(object));

    var block = Expression.Block(
        Expression.IfThenElse(
            checkNullExpression,
            Expression.Return(returnTarget, secondParent),
            Expression.Return(returnTarget, firstParent)),
        Expression.Label(returnTarget, Expression.Constant(new object())));

    var sortExpression = Expression.Lambda<Func<TSource, object>>(block, param);

    if (ascending)
        return source.OrderBy(sortExpression);

    return source.OrderByDescending(sortExpression);
}

Upvotes: 1

Views: 1249

Answers (2)

Stilgar
Stilgar

Reputation: 23571

I believe Entity Framework does not support statement lambdas only expressions. You may have more luck if you can somehow convert the if statement into a conditional expression.

It seems that you are trying to sort on multiple properties. I think this would be easier to do using the ThenBy method.

Upvotes: 4

TomTom
TomTom

Reputation: 62157

Yeah. How do you think entity framework is gong to translate your custom expression into - ah - SQL?

Hint: it can not. SImple like that. it tells you that.

I suggest you scrap the sort, get EF return whatever you ask for as IEnumerable, THEN sort the result of that (which then happens not in SQL but using LINQ for Objects because EF ends at the IEnumerable). This should allow the sort to happen in memory where the .NET runtime can make sense out of your custom expression.

Upvotes: -3

Related Questions