SDw*_*rfs 3 c# linq entity-framework iqueryable
我已经定义了一个超类"有效性",它定义了一个对象是"有效"的时间跨度(ValidFrom/ValidTo).它还定义了一个函数,该函数对于给定的时间戳返回true,iff(=且当且仅当)(派生的)对象此时有效.
public class Validity
{
public int ValidityID { get; set; }
public DateTime? ValidFrom { get; set; }
public DateTime? ValidTo { get; set; }
bool isValidAt(DateTime time)
{
return (ValidFrom == null || ValidFrom >= time)
&& (ValidTo == null || ValidTo < time);
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想编写一些在LINQ查询中检查isValidAt的函数.我想这可以通过IQueriable,但我没有找到如何...以下代码剪切是我想要以某种方式"工作"(特别是where n.isValidAt(t)).那么,如何实现呢?
public class Node : Validity {
public int NodeID { get; set; }
public static getFirstNode(DateTime t)
{
MyContext db = new MyContext();
var items = from n in db.Nodes
where n.isValidAt(t)
orderby n.NodeID descending
select n;
return items.FirstOrDefault<Node>();
}
}
Run Code Online (Sandbox Code Playgroud)
---工作解决方案---
我需要调整Zaid Masud的解决方案,以使其正常工作.请注意,我必须删除this参数列表中的内容(现在是方法定义public static IQueryable<T> isValidAt<T>(IQueryable<T> query, DateTime time) where T : Validity).这是源代码:
public class Validity
{
public int ValidityID { get; set; }
public DateTime? ValidFrom { get; set; }
public DateTime? ValidTo { get; set; }
public static IQueryable<T> isValidAt<T>(IQueryable<T> query, DateTime time) where T : Validity
{
return query.Where<T>(c => (c.ValidFrom == null || c.ValidFrom >= time)
&& (c.ValidTo == null || c.ValidTo < time));
}
}
Run Code Online (Sandbox Code Playgroud)
您需要将bool isValidAt(DateTime time)方法声明为protected,以便派生类可以访问它:
protected bool IsValidAt(DateTime time)
Run Code Online (Sandbox Code Playgroud)
但是,在您进行此编译之后,我怀疑您的LINQ to SQL提供程序是否能够将查询转换为SQL.您可能需要在LINQ查询中嵌入逻辑并编写如下内容:
var items = from n in db.Nodes
where (n.ValidFrom == null || n.ValidFrom >= t) && (n.ValidTo == null || n.ValidTo < t)
orderby n.NodeID descending
select n;
Run Code Online (Sandbox Code Playgroud)
这将有效,但更好的选择是创建以下类型的扩展方法:
public static class ValidityExtensions
{
public static IQueryable<T> Valid<T>(this IQueryable<T> validities, DateTime time) where T : Validity
{
return validities.Where(v => (v.ValidFrom == null || ValidFrom >= time) && (v.ValidTo == null || v.ValidTo < time));
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以使用如下:
var items = from n in db.Nodes.Valid(time)
orderby n.NodeID descending
select n;
Run Code Online (Sandbox Code Playgroud)