Linq To Entities中的可重用函数

问题描述 投票:1回答:1

我有2个可重用的函数返回列表。如果将这些函数的代码直接写入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();
entity-framework linq linq-to-entities
1个回答
1
投票

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

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

细节:

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

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

什么是表达式树?

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

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

它也可以看作是一个表达式>

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

为什么这一切?

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

当你有你提取的Func <...>时,有一点问题...在结果表达式树的某个点上有类似的东西......拿参数x和CALL静态Func ...表达式树做不再包含对Func内部发生的事情的描述,只是对它的调用...只要你想将它编译成.net运行时可执行函数,它就是有趣和游戏......但当你试图将它解析为SQL,LINQ to entiteis不知道相应的SQL为“调用一些c#函数”...因此它告诉你表达式树的这一部分不能转换成存储表达式

© www.soinside.com 2019 - 2024. All rights reserved.