上下文 - 这个问题:按 DayOfWeek 排序,星期从星期一开始
我想重构排序代码,而不是难以理解的 lambda
s => ((int)s.DayOfWeek + 6) % 7
写类似的东西
s => GetDayNumberInWeek(s.DayOfWeek, weekStartsWith: DayOfWeek.Monday)
事实证明,表达式树不支持命名参数,即 将不得不写得不太清楚:
s => GetDayNumberInWeek(s.DayOfWeek, DayOfWeek.Monday)
就这样吧,但是怎么做呢?如果你写
static int GetDayNumberInWeek(DayOfWeek dayOfWeek, DayOfWeek weekStartsWith)
{
int daysInWeek = 7;
return ((int)dayOfWeek + daysInWeek - (int)weekStartsWith) % daysInWeek;
}
当然,这种排序将开始在客户端执行,但这是不可取的。
如果我从该方法返回任何Expression
内容,那么 EF 会发誓缺乏实现IComparable
。
这个问题有解决方案吗?
您需要生成整个 lambda,而不仅仅是右侧。
举一个更简单的例子,这样 Body 的创建就不会嘈杂:
让你拥有:
并且您想动态构建键选择器:
我们完全取出选择器:
并展开生成的代码:
如果您需要从 Schedule 取消绑定 BuildDayOfWeekSelector - 只需将其设为 Generic(但您必须在调用时指定类型)。
其余的动态 - 参数 weekStartsWith - 作为 BuildKeySelector 中的参数下降,并在构建主体时用作
Expression.Constant(weekStartsWith);
需要手动构建的确切树可以很容易地窥探 - 为编译器生成的 lambda 提取本地,并将其部署在调试器中。
一切顺利:
像这样使用: