【发布时间】:2018-06-01 17:16:38
【问题描述】:
我的项目有许多带有日期字段的对象,我经常需要选择一个日期范围内的所有对象。
例如:
public class Contract
{
public DateTime SignDate { get; set; }
public DateTime ReleaseDate { get; set; }
}
public class PersonalCheck
{
public DateTime SignDate { get; set; }
public DateTime ProcessDate { get; set; }
public DateTime VoidDate { get; set; }
}
如果我只关心 SignDate,那就很容易了。我会声明一个接口...
public interface IObjectWithSignDate
{
DateTime SignDate { get; set; }
}
...更改我的其他对象以从它继承,然后创建一个这样的方法:
public static IQueryable<T> SignedWithin<T>(this IQueryable<T> items, DateTime start, DateTime end) where T : IObjectWithSignDate
{
return items.Where(q => q.SignDate >= start && q.SignDate <= end);
}
如何避免为 ReleaseDate、ProcessDate、VoidDate 等重写此函数?我可以让这个方法接受任何对象的 IQueryable 和一个告诉它运行这个选择器的日期字段的变量吗?
请注意,这必须能够 a) 在 LinqToEntities 中执行以针对数据库运行 b) 不会增加很多开销(因为我担心反射可能会这样做)
【问题讨论】:
-
如果您添加
Expression<Func<T, bool>>的参数,您可以为您的where 子句传入谓词。您的调用者仍需要知道要比较的对象上的哪些日期,但它不会与特定的方法实现绑定。 -
难道我还不需要为每个日期字段创建一个单独的谓词吗?
-
来自呼叫站点,是的。您将不得不在某处指定日期字段。
-
我的问题是,如果我为我的应用程序中的 6 个以上不同日期字段中的每一个创建一个谓词(它们都使用相同的比较规则),我需要对所有这些字段进行单元测试.这是我已经遇到的问题。我正在寻找一种方法将方法计数减至 1 以使其变得漂亮和干燥。
-
嗯,你有 6+ 种不同的逻辑流程。它们可能相似,但它们都是不同的。如果您走表达式路线,您可以通过提供表达式和 IQueryable 作为测试方法的参数来使用一种方法测试您的案例,并通过一个方法调用所有内容,但这只是将多个单元测试的问题变成了多个测试案例。我不知道你会如何摆脱它,但我可能会遗漏一些东西。
标签: c# linq datetime generics compare