Linq To Entites中的可重用函数

时间:2018-04-05 09:32:25

标签: entity-framework linq linq-to-entities

我有两个返回列表的可重用函数。如果将这些函数的代码直接写入linq到实体查询,那么一切都很好。但是,将它们分离为函数会导致错误,因为它无法转换为存储的表达式。我确信必须有办法做到这一点。任何想法如何解决这个问题。理想情况下,我希望可重复使用的部分也可以在linq之外用于实体查询。

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();

1 个答案:

答案 0 :(得分:1)

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

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

细节:

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

LINQ查询与表达式树一起工作......换句话说:只是因为您直接在查询中输入的代码以及您键入静态Func&lt; ...&gt;的代码。看起来一样,实际上是一样的,两种情况下得到的表达式树都不一样了

什么是表达式树?

想象一个更简单的查询,比如... someIQueryable.Where(x =&gt; x.a == 1&amp;&amp; x.b ==“foo”)

传递给Where(...)的lamda可以看作是一个可以用作Func的straigt forward c#lambda表达式

它也可以看作表达式&gt;

后者是构成表达式的对象树,换句话说是关于方式的描述,因为传入的参数可以在没有实际可执行代码的情况下被评估为bool,而只是关于什么的描述do ...从参数中获取成员a,将其与常量1进行比较...取结果的结果的布尔值:从参数中取出成员b,将其与常量进行比较“foo”...返回布尔值AND

的结果

为什么这一切?

这是LINQ的工作方式...... LINQ to entiteis接受表达式树,查看所有操作,找到相应的SQL,并构建一个最终执行的SQL语句......

当你提取了Func&lt; ...&gt;有一点问题...在结果表达式树的某个点上有类似的东西......取参数x并调用静态函数...表达式树不再包含对Func中发生的事情的描述,但只是对它的调用...只要你想将它编译成.net运行时可执行函数,它就是有趣和游戏......但是当你尝试将它解析成SQL时,LINQ to entiteis不知道用于“调用一些c#函数”的相应SQL ...因此它告诉您表达式树的这一部分无法转换为商店表达式