Невозможно привести тип 'System.Int32' к типу 'System.Object во время кода EF. Первая функция заказа - PullRequest
0 голосов
/ 31 декабря 2018

Я использую шаблон спецификации в EF Code First.Когда я делаю заказ по операции, VS выдает новое исключение

enter image description here

Шаблон спецификации копируется из eShopOnWeb

Я просто немного изменился, вот мой код изменения:

public class Specification<T> : ISpecification<T>
{ 

    public Expression<Func<T, object>> OrderBy { get; private set; }

    public Specification(Expression<Func<T, bool>> criteria)
    {
        Criteria = criteria;
    }

    public Specification<T> OrderByFunc(Expression<Func<T, object>> orderByExpression)
    {
        OrderBy = orderByExpression;
        return this;
    }
}

Вот мой код вызова, он очень прост:

static void TestSpec()
    {
        var spec = new Specification<ExcelData>(x => x.RowIndex == 5)
            .OrderByFunc(x => x.ColumnIndex);

        using (var dbContext = new TechDbContext())
        {
            var top10Data = dbContext.ExcelData.Take(10).ToList();
            var listExcel = dbContext.ApplySpecification(spec).ToList();

            Console.WriteLine();
        }
    }

Если я прокомментирую OrderByFunc , тогда у меня все нормально.

без ошибок. Я много раз пытался найти сообщение об ошибке в Google, но ни один из ответов не является моим случаем.

Поэтому я должен задать вопрос здесь.

Когда я отлаживаю OrderBy свойство в SpecificationEvaluator.cs , я обнаружил, что есть Преобразовать метод.enter image description here

Итак, я знаю, что ошибка связана с ошибкой приведения, но как мне исправить эту ошибку типа приведения?

Пожалуйста, помогите мне!

1 Ответ

0 голосов
/ 04 января 2019

Решение состоит в том, чтобы создать новое лямбда-выражение с удаленным приведением (Convert), а затем использовать его для вызова метода Queryable class OrderBy / OrderByDescending либо динамически (с использованием диспетчеризации или отражения DLR), либо путемиспуская Expression.Call к нему.

Для первой части добавьте следующий вспомогательный метод к классу SpecificationEvaluator:

static LambdaExpression RemoveConvert(LambdaExpression source)
{
    var body = source.Body;
    while (body.NodeType == ExpressionType.Convert)
        body = ((UnaryExpression)body).Operand;
    return Expression.Lambda(body, source.Parameters);
}

Затем замените код

query = query.OrderBy(specification.OrderBy);

с

query = Queryable.OrderBy((dynamic)query, (dynamic)RemoveConvert(specification.OrderBy));

или

var keySelector = RemoveConvert(specification.OrderBy);
query = query.Provider.CreateQuery<T>(Expression.Call(
    typeof(Queryable), nameof(Queryable.OrderBy),
    new[] { typeof(T), keySelector.ReturnType },
    query.Expression, keySelector));

Аналогично для specification.OrderByDescending.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...