我经常需要通过 publishStart
、publishEnd
、active
等字段来限制 SELECT
我在几个不同的表中有这些字段。所以只应选择行,即
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 行。
我该怎么做? 有没有更好的方法来清理代码?
最佳答案
要定义扩展,您需要一个静态类。你可以把它放在你喜欢的任何命名空间中,只记得将它包含在你的使用中。
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
的存在。这应该是实现这些字段的类或定义它们的契约(接口(interface))。
然后你可以这样调用它:
var item = db.myTable.Active().SingleOrDefault(...);
更多关于扩展方法的信息:http://msdn.microsoft.com/en-us/library/bb383977.aspx
由于到处都有很多评论,我将在这里添加一个接口(interface)解决方案的简要说明......
问题中不清楚这三个过滤字段是否有通用实现或定义它们的接口(interface)。如果不是,要使上述工作正常,您将不会:
- 实现这些字段的基类。在这种情况下,您可以将
YourEntityType
替换为YourBaseEntityType
。 - 定义字段的接口(interface)。在这种情况下,您需要让您的类实现这些字段。如果类是自动生成的(例如首先是 Entity Framework 模型/数据库),那么您可以实现部分类,让它们实现接口(interface)。在这种情况下,您可以将
YourEntityType
替换为IYourContract
。
关于c# - Linq扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14221143/