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

jef*_*han 6 entity-framework casting specifications sql-order-by

我在EF Code First中使用规范模式.当我通过操作进行排序时,VS会抛出一个新的异常

在此输入图像描述

规范模式是从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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的调用代码,它非常简单:

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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果我评论OrderByFunc,那么一切都很好.没有错误抛出vs.

我曾多次尝试在谷歌中搜索错误消息,但答案都不是我的情况.

所以我在这里问一个问题.

当我在SpecificationEvaluator.cs中调试OrderBy属性时,我发现有一个Convert方法. 在此输入图像描述

所以我知道错误是关于强制转换错误,但是如何修复此强制转换类型错误?

请帮我!

Iva*_*oev 4

解决方案是创建新的 lambda 表达式并Convert删除强制转换 (),然后使用它动态(使用 DLR 调度或反射)或通过向其发出来调用QueryableOrderBy/方法。OrderByDescendingExpression.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);
}
Run Code Online (Sandbox Code Playgroud)

然后替换代码

query = query.OrderBy(specification.OrderBy);
Run Code Online (Sandbox Code Playgroud)

与任一

query = Queryable.OrderBy((dynamic)query, (dynamic)RemoveConvert(specification.OrderBy));
Run Code Online (Sandbox Code Playgroud)

或者

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));
Run Code Online (Sandbox Code Playgroud)

对 做类似的事情specification.OrderByDescending