Linq To 实体中的可重用函数

Reusable Functions in Linq To Entites

我有 2 个 return 列出的可重用函数。如果将这些函数的代码直接写入 linq to entities 查询,一切都很好。但是,将它们分离到函数中会导致错误,因为它无法转换为存储的表达式。我相信一定有办法做到这一点。任何想法如何解决这个问题。理想情况下,我希望可重用部分也能在 linq to entity 查询之外使用。

var activityBands = DbContext.ActivityBand
                .OrderBy(x => x.ActivityBandDescription)
                .Where(x => x.Active && x.ClientAccountId == clientAccountId)
                .Select(x => new ActivityBandDdl
                {
                    Name = x.ActivityBandDescription,
                    ActivityBandId = x.ActivityBandId,
                    ApplyAwr = x.ApplyAwr,
                    AssignmentLineTimeTypeIds = TimeTypesForActivityBand(x.DailyRate) ,
                    AssignmentTypeIds = AssTypesForActivityBand(x.StagePayment)
                }).ToList();          



public static Func<bool, List<int>> TimeTypesForActivityBand =
                     (dailyRate) => (new int[] { 1, 2, 3, 4 }).Where(t =>
                       ((t != 1 && t != 2) || !dailyRate) //No Timed or NTS for daily rates
                     ).ToList();


public static Func<bool, List<int>> AssTypesForActivityBand =
                             (stagePayment) => (new int[] { 2,3,4,5,6,7,8,9,10 }).Where(t =>
                               ( t!=2 || !stagePayment) //Only stage pay ass have stage pay activity bands
                             ).ToList();

TL;DR; 针对您的问题的建议解决方案:

获取 LinqKit ... 看看它的 Expand() 函数(在文档中:组合表达式) https://github.com/scottksmith95/LINQKit#combining-expressions

详情:

问题归结为:两种情况下的查询有什么区别...

LINQ 查询使用表达式树...换句话说:只是因为您直接在查询中键入的代码和您在静态 Func<...> 中键入的代码看起来相同,实际上, 是一样的,两种情况下得到的表达式树是不一样的

什么是表达式树?

想象一个更简单的查询,例如... someIQueryable.Where(x => x.a==1 && x.b=="foo")

传递给 Where(...) 的 lamda 可以看作是一个直接向前的 c# lambda 表达式,可以用作 Func

也可以看做一个表达式>

后者是形成表达式的对象树,换句话说是关于方式的描述,因为传入的参数可以评估为 bool 而无需实际具有可执行代码,而只是关于的描述要做什么...从参数中取出成员 a,equality-compare 将其赋给常量 1 ...将结果与结果进行布尔值与运算:从参数中取出成员 b,equality-compare 它到常量 "foo" ... return 布尔值 AND

的结果

为什么会这样?

这是 LINQ 的工作方式 ... LINQ to entiteis 获取表达式树,查看所有操作,找到相应的 SQL,并构建一个 SQL 语句,该语句在结束...

当你有提取的 Func<...> 时有一个小问题......在生成的表达式树中的某个点有类似......采用参数 x 并调用静态 Func .. . 表达式树不再包含对 Func 内部发生的事情的描述,而只是对其的调用......只要你想将其编译为 .net 运行时可执行函数,这一切都很有趣和游戏......但是当您尝试将其解析为 SQL 时,LINQ to entiteis 不知道 "call some c# function" 对应的 SQL ...因此它告诉您表达式树的这一部分不能转换为存储表达式