0

我编写了一个通用扩展方法,它可以消除解析查询字符串或路由数据参数并根据该参数过滤特定可查询对象的痛苦。

  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;
        }
    }

这在工作时允许我在我的控制器中编写以下干净的代码行,而不必每次都复制粘贴上述块的非通用版本。

 return aDB.GetAll<Product>().VaryBy(x=> x.Category.Id, "categoryid", this);

遗憾的是,在结果上调用 ToList() 时会引发异常:“LINQ to Entities 不支持 LINQ 表达式节点类型‘Invoke’。”

我有点理解为什么会这样。我还读到我可能会为此使用LinqKit的 AsExpandable ,但在我了解如何自己完成这项工作之前,我有点犹豫是否使用他们的“自动解决方案”,我对使用不同的解决方案持开放态度方法也一样,只是想在这里学习!

4

2 回答 2

0

根据经验,请考虑如何将此请求转换为 TSQL。如果你不能把它翻译成原生的 TSQL,很可能任何框架也做不到。If 子句和外部方法调用都是将其转换为单个查询的障碍。

于 2012-08-31T13:59:19.213 回答
0

感谢John Skeet对我的问题的回答简化了这个问题,我成功地创建了我的 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;
        }
    }
于 2012-09-04T08:08:33.560 回答