我有两个返回列表的可重用函数。如果将这些函数的代码直接写入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();
答案 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 ...因此它告诉您表达式树的这一部分无法转换为商店表达式