我经常需要按publishStart
,publishEnd
,active
我在几个不同的表格中有这些字段。因此,只应选择
行a: active == true;
b: publishStart < now;
c: publishEnd > now;
所以,例如:
db.myTable.SingleOrDefault(a => (a.ID == _theID
//now the active and start-end part:
&& ((a.publishEnd > DateTime.Now) || (a.publishEnd == null))
&& ((a.publishStart <= DateTime.Now) || (a.publishStart == null))
&& a.active == true));
这有点冗长,所以我想知道是否有可能创建一个(扩展名?) - 方法,如:
db.myTable.SingleOrDefault(a => (a.ID == _theID).isActive()
isActive()
提供上述代码段的3行。
我怎么能这样做? 有没有更好的方法来清理代码?
答案 0 :(得分:13)
要定义扩展,您需要一个静态类。您可以将它放在您喜欢的任何名称空间中,只需记住将其包含在您的使用中。
public static class Extensions
{
public static IQueryable<T> Active<T>(this IQueryable<T> source)
where T : YourEntityType
{
return source.Where(a => ((a.publishEnd > DateTime.Now) || (a.publishEnd == null))
&& ((a.publishStart <= DateTime.Now) || (a.publishStart == null))
&& a.active == true);
}
}
请注意YourEntityType
。这用于确保方法知道publishStart
,publishEnd
和active
的存在。这应该是实现这些字段的类或定义它们的契约(接口)。
然后你会这样称呼它:
var item = db.myTable.Active().SingleOrDefault(...);
有关扩展方法的更多信息,请访问:http://msdn.microsoft.com/en-us/library/bb383977.aspx
由于有很多评论突然出现,我将在这里添加一个关于界面解决方案的简要说明......
在问题中是否存在三个过滤字段的常见实现或定义它们的接口尚不清楚。如果没有,为了使上述工作,您将不会:
YourEntityType
替换为YourBaseEntityType
。YourEntityType
替换为IYourContract
。答案 1 :(得分:4)
只需定义一个这样的界面
public interface IHaveAActivityPeriod
{
Boolean active { get; }
DateTime? publishStart { get; }
DateTime? publishEnd { get; }
}
并将其添加到所有相关课程中。
public class Foo : IHaveAActivityPeriod { [...] }
public class Bar : IHaveAActivityPeriod { [...] }
现在您可以使用此扩展方法
public static class Extensions
{
public static Boolean IsActive(this IHaveAActivityPeriod item)
{
var now = DateTime.Now;
return item.active &&
(item.publishStart <= now)
(!item.publishEnd.HasValue || (item.publishEnd > now));
}
}
在每个实施IHaveAActivityPeriod
的实例上。
var foo = new Foo();
var isFooActive = foo.IsActive();
var bar = new Bar();
var isBarActive = bar.IsActive();
我完全错过了构建扩展方法的可能性,该扩展方法执行序列的过滤而不是一次查看单个实体。只需将flem的答案中的扩展方法作为类型约束在接口中抛出。
public static class Extensions
{
public IQueryable<T> IsActive<T>(this IQueryable<T> sequence)
where T : IHaveAActivityPeriod
{
return source.Where(item =>
item.active &&
(item.publishStart <= now) &&
(!item.publishEnd.HasValue || (item.publishEnd > now));
}
}
答案 2 :(得分:3)
public static class Extensions
{
public static IEnumerable<MyClass> isActive(this IEnumerable<MyClass> list)
{
return list.Where(a =>
((a.publishEnd > DateTime.Now) || (a.publishEnd == null))
&& ((a.publishStart <= DateTime.Now) || (a.publishStart == null))
&& a.active == true);
}
}