【问题标题】:Predicate for reuseable datetime filter可重用日期时间过滤器的谓词
【发布时间】:2013-03-15 17:05:55
【问题描述】:

我有许多包含日期时间的对象。我发现我正在重用 lambda 语句:

Where(x => EntityFunctions.TruncateTime(x.Date.Value) >= EntityFunctions.TruncateTime(startDate) &&
    EntityFunctions.TruncateTime(x.Date.Value) <= EntityFunctions.TruncateTime(endDate));

在许多地方。我想用一个谓词替换这个表达式,这个谓词可以在我的对象列表中使用。

【问题讨论】:

  • 请不要只要求我们为您解决问题。向我们展示是如何尝试自己解决问题的,然后向我们确切地展示结果是什么,并告诉我们您为什么觉得它不起作用。请参阅“What Have You Tried?”了解您真正需要阅读的优秀文章。
  • 您在寻找DateTime.Date吗?更具体地说,EntityFunctions.TruncateTimeDateTime.Date 有何不同?
  • startDateendDate 是本地变量还是类级别变量?
  • 我基本上有一个 List,每个对象都有一个 Date 属性。 startDate 和 endDate 将是我可以传入的范围。根据我目前阅读的内容,我相信它看起来像: List newList = myList.Find(IsInRange(DateTime.Now, DateTime.Now .AddDays(7)); 我尝试将其设置为谓词和 Func。@AustinSalonen - EnitityFunctions.TruncateTime 内置于 .Net 中,允许您忽略在 lambda 表达式中使用实体框架时的 DateTime 对象。
  • @JohnSaunders - 谢谢你的链接。将来,我将尝试改进我最初的问题,并提供更多关于我尝试过的细节。

标签: c# date filter predicate


【解决方案1】:

如果startDateendDate 是类级别的变量,您可以只使用一个方法:

bool FilterDate(YourEntityType x)
{
    return EntityFunctions.TruncateTime(x.Date.Value) >= EntityFunctions.TruncateTime(startDate) &&
           EntityFunctions.TruncateTime(x.Date.Value) <= EntityFunctions.TruncateTime(endDate));
}

这将通过以下方式调用:

var results = myobjects.Where(FilterDate);

但是,如果它们是本地变量,则您的 lambda 将关闭两个局部变量(startDateendDate),如果您重用单个委托,这可能会导致行为发生变化,除非范围始终保持不变.

一种选择可能是创建一个辅助方法:

static Func<YourEntityType, bool> CreateFilter(DateTime startDate, DateTime endDate)
{
     Func<YourEntityType, bool> func = x => EntityFunctions.TruncateTime(x.Date.Value) >= EntityFunctions.TruncateTime(startDate) &&
EntityFunctions.TruncateTime(x.Date.Value) <= EntityFunctions.TruncateTime(endDate));
     return func;
}

你可以这样写:

var results = myobjects.Where(CreateFilter(startDate, endDate));

【讨论】:

  • Reed,我相信这非常接近我想要实现的目标。我没有考虑过使用辅助函数。我会在今天晚些时候试一试。谢谢!
【解决方案2】:

定义另一个谓词方法,它将检查YourType 是否有正确的日期

private static bool IsObjectHasNeccesaryDate(YourType obj, DateTime startDate, DateTime endDate)
{
    return EntityFunctions.TruncateTime(obj.Date.Value) >= EntityFunctions.TruncateTime(startDate) 
        && EntityFunctions.TruncateTime(obj.Date.Value) <= EntityFunctions.TruncateTime(endDate);
}

然后你可以使用 lambda 语法来使用它,像这样:

myobjects.Where(obj => IsObjectHasNeccesaryDate(obj, startDate, endDate));

请注意,它将捕获您的 startDateendDate 变量。

【讨论】:

  • 这只有在startDateendDate 是类级别变量而不是本地变量时才有效。
  • 更新了我的答案。感谢您的注意。将该谓词设为静态,以便显而易见,他不会访问私有对象的状态
【解决方案3】:

您可以将表达式定义为 Func:

Func<object,bool> exp = x => 
    EntityFunctions.TruncateTime(x.Date.Value) >= EntityFunctions.TruncateTime(startDate) 
    && EntityFunctions.TruncateTime(x.Date.Value) <= EntityFunctions.TruncateTime(endDate);

用您正在使用的任何类型替换对象。然后将 Func 传递给 Where:

Where(exp);

【讨论】:

    猜你喜欢
    • 2012-06-26
    • 1970-01-01
    • 2019-11-24
    • 2017-03-11
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 2015-07-22
    • 2017-09-19
    相关资源
    最近更新 更多