【发布时间】:2018-08-10 23:51:22
【问题描述】:
我正在重构一些代码,试图使其更具自我记录性。当前代码对 OData 服务进行了查询,如下所示:
return context.MessageLog.Where
(
x =>
(
x.Status == MessageStatus.Success
|| x.Status == MessageStatus.Failure
)
&& x.Direction == MessageDirection.Inbound
&& x.ResponseDate == new DateTimeOffset(new DateTime(1900, 01, 01))
);
我希望更改它以使用 Linq 表达式。
我可以将所有逻辑移动到一个表达式中并让代码运行context.MessageLog.Where(MessageIsPendingResponse);。
但是,我想为不同的条件创建表达式:MessageIsProcessed(即现在处于成功或失败状态)、MessageIsInbound 和ResponseNotYetSent(响应日期为空)。
我可以将这些与多个 where 语句结合起来,如下所示:
return context.MessageLog
.Where(MessageLogExpression.MessageIsProcessed)
.Where(MessageLogExpression.MessageIsInbound)
.Where(MessageLogExpression.ResponseNotYetSent);
(MessageLogExpression 是我用来包含这些预定义表达式的类)。
问题 1
这是组合语句的最佳方式,还是会冒先过滤错误字段的风险(例如,Linq 是否将所有条件组合到单个查询中并允许查询引擎(以 SQL 术语)确定最佳执行计划;还是我们强制它先过滤状态字段?
问题 2
以上对于我们有AND 加入我们的表达式的情况非常有用;但是我们将如何处理OR?
我认为有一些方法可以将这些结合起来,但找不到任何明显的东西。我怀疑存在这样的事情?
return context.MessageLog.Where(new OrExpression(MessageIsSuccess,MessageIsFailure));
问题 3
有没有一种在另一个表达式定义中组合表达式的好方法?例如类似于下面的代码(只有一个可以编译的版本)?
public static Expression<Func<MessageLogRecord, bool>> MessageIsPendingResponse
{
get
{
Expression<Func<MessageLogRecord, bool>> expr = x =>
MessageIsProcessed(x)
&& MessageIsInbound(x)
&& ResponseNotYetSent(x);
return expr;
}
}
附录:上述表达式的代码:
public class MessageLogExpression
{
public static Expression<Func<MessageLogRecord, bool>> MessageIsProcessed
{
get
{
Expression<Func<MessageLogRecord, bool>> expr = x =>
(
x.Status == MessageStatus.Success
|| x.Status == MessageStatus.Failure
);
return expr;
}
}
public static Expression<Func<MessageLogRecord, bool>> MessageIsInbound
{
get
{
Expression<Func<MessageLogRecord, bool>> expr = x =>
x.Direction == MessageDirection.Inbound;
return expr;
}
}
static readonly DateTimeOffset NullDate = new DateTimeOffset(new DateTime(1900, 01, 01));
public static Expression<Func<MessageLogRecord, bool>> ResponseNotYetSent
{
get
{
Expression<Func<MessageLogRecord, bool>> expr = x =>
x.ResponseDate == NullDate; //todo: test if this works or if I have to define the value within the expression
return expr;
}
}
}
【问题讨论】:
标签: c# linq odata linq-expressions