Entity framework Queryable上的泛型扩展方法,在将表达式转换为Linq to实体可用的内容时调用时崩溃

Entity framework Queryable上的泛型扩展方法,在将表达式转换为Linq to实体可用的内容时调用时崩溃,entity-framework,generics,expression,Entity Framework,Generics,Expression,我编写了一个通用扩展方法,该方法省去了解析querystring或route数据参数并基于该参数过滤某个queryable的麻烦 public static IQueryable VaryBy<T>(this IQueryable<T> input,Func<T,int> navigationalproperty,string routeparameter,PageController currentPagecontroller) where T : En

我编写了一个通用扩展方法,该方法省去了解析querystring或route数据参数并基于该参数过滤某个queryable的麻烦

  public static IQueryable VaryBy<T>(this IQueryable<T> input,Func<T,int> navigationalproperty,string routeparameter,PageController currentPagecontroller) where T : EntityObject
    {
        string navid = currentPagecontroller.GetFromRequestOrRouteData(routeparameter);
        if (!String.IsNullOrEmpty(navid))
        {
            int navidasint = int.Parse(navid);
            //return input.Where(x => navigationalproperty(x) == navidasint);

            return (from var in input
                    let result = navigationalproperty(var)
                    where result == navidasint
                    select var);
        }
        else
        {
            return input;
        }
    }
public static IQueryable VaryBy(此IQueryable输入,Func NavigationProperty,string routeparameter,PageController currentPagecontroller),其中T:EntityObject
{
字符串navid=currentPagecontroller.GetFromRequestOrRouteData(routeparameter);
如果(!String.IsNullOrEmpty(navid))
{
int navidasint=int.Parse(navid);
//返回输入。其中(x=>NavigationProperty(x)=navidasint);
返回(来自输入中的var)
让结果=导航属性(var)
其中result==navidasint
选择var);
}
其他的
{
返回输入;
}
}
在工作时,这将允许我在控制器中编写以下干净的代码行,而不必每次都复制粘贴上述块的非通用版本

 return aDB.GetAll<Product>().VaryBy(x=> x.Category.Id, "categoryid", this);
返回aDB.GetAll().VaryBy(x=>x.Category.Id,“categoryid”,this);
遗憾的是,在对结果调用ToList()时,这会引发一个异常:“LINQ to实体中不支持LINQ表达式节点类型“Invoke”。

我有点理解为什么会这样。我还读到,我可能会使用的是一个可扩展的,但我有点犹豫使用他们的“自动解决方案”,在我了解如何使这项工作我自己,
我也对使用不同方法的解决方案持开放态度,只是在这里尝试学习

根据经验,考虑如何将此请求转换为TSQL。如果您不能将其转换为本机TSQL,那么很可能任何框架也无法实现。If子句和外部方法调用都是将其转换为单个查询的拦截器。

多亏了对我问题的简化,我成功地创建了VaryBy函数,如下所示:

public static IQueryable VaryBy<T>(this IQueryable<T> input,Expression<Func<T,int>> navigationalproperty,string routeparameter,PageController currentPagecontroller) where T : EntityObject
    {
        string navid = currentPagecontroller.GetFromRequestOrRouteData(routeparameter);
        if (!String.IsNullOrEmpty(navid))
        {
            int navidasint = int.Parse(navid);
            Expression equals = Expression.Equal(navigationalproperty.Body, Expression.Constant(navidasint));
            return input.Where(Expression.Lambda<Func<T, bool>>(equals, navigationalproperty.Parameters));

        }
        else
        {
            return input;
        }
    }
public static IQueryable VaryBy(此IQueryable输入、表达式导航属性、字符串routeparameter、PageController currentPagecontroller),其中T:EntityObject
{
字符串navid=currentPagecontroller.GetFromRequestOrRouteData(routeparameter);
如果(!String.IsNullOrEmpty(navid))
{
int navidasint=int.Parse(navid);
Expression equals=Expression.Equal(navigationProperty.Body,Expression.Constant(navidasint));
返回input.Where(Expression.Lambda(equals,NavigationProperty.Parameters));
}
其他的
{
返回输入;
}
}

我知道这条经验法则:)另外,if子句不是问题,它不会被翻译,因为我只是返回一个不同的IQueryable。这里唯一的问题是调用get的Func,而不是将其转换为包含“==navidasint”部分的可编译表达式。。(我认为)实际上,它可能是NavigationProperty,您将其声明为Func而不是表达式。因此,Func无法计算和解析,只能执行。尝试暂时删除Let和Where子句,并查看它是否编译并运行以隔离此子句。