.NET 3.5 Framework上的C#
所以,我正在尝试进行有效的查询,以查找要从我的系统中清除的所有电子邮件。应该清除的是已经尝试的电子邮件(Datetime列LastAttempted不为null)和保留的天数(int列RetentionDays)已经过去。这有效,但我知道它会把所有东西都拉回来并在内存中过滤。
这就是我现在所拥有的
var emails = dbContext.Emails
.Where(x => x.LastAttempted.HasValue == true)
.ToList()
.Where(x => ((DateTime)x.LastAttempted).AddDays(x.RetentionDays) <= DateTime.Now);
如何更新此内容,以便仅从SQL Server中提取我关注的记录?
答案 0 :(得分:4)
使用EntityFunctions.AddDays
在EF查询中为DateTime
添加天数。
var emails = dbContext.Emails
.Where(x => x.LastAttempted.HasValue &&
EntityFunctions.AddDays(x.LastAttempted, x.RetentionDays)
<= DateTime.Now);
答案 1 :(得分:1)
这部分查询:
dbContext.Emails
.Where(x => x.LastAttempted.HasValue == true)
.ToList();
将在sql server中执行,并且在调用ToList时将返回内存集合。
然后是查询的最后一部分:
.Where(x =>
((DateTime)x.LastAttempted).AddDays(x.RetentionDays) <= DateTime.Now);
将在内存集合中的上述项目中执行。
所以问题依赖于查询的最后一部分。您可以使用AddDays
的方法EntityFunctions
来避免这种情况,并避免在内存集合中进行第二次过滤。这可以完成如下:
dbContext.Emails
.Where(x => x.LastAttempted.HasValue == true &&
EntityFunctions.AddDays(x.LastAttempted, x.RetentionDays)
<= DateTime.Now);
答案 2 :(得分:0)
在查询末尾移动ToList()
var now = DateTime.Now;
var emails = dbContext.Emails
.Where(x => x.LastAttempted.HasValue &&
EntityFunctions.AddDays((DateTime)x.LastAttempted, x.RetentionDays) <= now).
ToList();
答案 3 :(得分:0)
您可以随时直接查询数据库,如下所示:
var items = dbContext.Database.SqlQuery<Email>("select * from Emails where LastAttempted Is Not Null And LastAttempted + RetentionDaya >= GetDate()", new SqlParameter[0]);
注意:我对您的实体,表格和列名称做了一些猜测。