在EF Code First Orderby Function期间无法将类型'System.Int32'强制转换为类型'System.Object

时间:2018-12-31 08:04:20

标签: entity-framework casting sql-order-by specifications

我在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 ,那么一切对我都很好。 vs.没有错误

我已经尝试过很多次在google中搜索错误消息,但是没有一个答案是我的情况。

所以我不得不在这里问一个问题。

当我在SpecificationEvaluator.cs中调试 OrderBy 属性时,发现有一个 Convert 方法。 enter image description here

所以我知道该错误与转换错误有关,但是如何解决此转换类型错误?

请帮助我!

1 个答案:

答案 0 :(得分:3)

解决方案是创建一个新的lambda表达式,并删除强制转换(Convert),然后使用它动态调用QueryableOrderBy / 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执行类似操作。