2015-03-13 70 views
0

在我的应用程序中,我试图在特定时间段内提取特定列中的值的总和。例如,如果我想要它为每个月拉总和我做了这样的事情.StartsWith和.Contains在比较日期时返回空值

var thisDate = DateTime.Now; 
var currentDay = thisDate.Day; 
var thisMonth = DateTime.Now.ToString("MM"); 
var thisYear = thisDate.Year.ToString(); 
var thisYearthisMonth = string.Format("{0}-{1}", thisYear, thisMonth); 
var SpecifiedTotal = (from t in db.Transaction 
         where t.AgentId == CurrentUser.SalesAgent.AgentId 
         && t.Status.Status == "Approved" 
         && t.DateApproved.ToString().StartsWith(thisYearthisMonth) 
         select (decimal?)t.AmountApproved).Sum() ?? 0; 

设置断点告诉我,SpecifiedTotal正在计算为零。我试图找出原因,通过删除行&& t.DateApproved.ToString().Contains(thisYearthisMonth),它评估到正确的价值。实质上,我试图在3月份的时间段内取出数值的总和,即2015-03年,所以我认为将存储的日期与通过查找从2015-03开始的任何日期进行比较是合理的。我可以做错什么?

回答

0

由于StartsWith比Contains更严格?你有没有试过检查你的DateApproved格式是什么格式?

+0

@JonSkeet你的代码是否考虑了某些月份的30天和某些月份的31天? – ibnhamza 2015-03-13 19:02:29

4

没有试图找出正是这种失败了,我会强烈建议不要使用字符串表示对这样的事情反正。只需使用DateTime比较代替 - 当然,假设DateApprovedDateTime列。 (如果不是的话,做起来很!)

var thisDate = DateTime.Now; 
var start = new DateTime(thisDate.Year, thisDate.Month, 1); 
var end = start.AddMonths(1); 
var specifiedTotal = (from t in db.Transaction 
         where t.AgentId == CurrentUser.SalesAgent.AgentId 
         && t.Status.Status == "Approved" 
         && t.DateApproved >= start && t.DateApproved < end 
         select (decimal?)t.AmountApproved).Sum() ?? 0; 

一般情况下,除非你实际上感兴趣的文本,你应该避免使用字符串操作。在这种情况下,您不是 - 您正在尝试对日期执行范围比较。这与他们的文字表示无关。

+0

@jtimperley如果像EF或Ling-To-SQL这样的提供者不能将LINQ转换为SQL,那么它将不会编译。如果实现Linq查询,它只会将记录拉到内存中。 – juharr 2015-03-13 18:39:20

+0

@juharr:不,它会经常*编译*,但无法执行。例如,尝试在查询中使用对'GetHashCode()'的调用...没有编译时错误,但在执行时会失败。但我同意它不会默默地将所有内容都拉进来,而是在客户端进行过滤。 – 2015-03-13 18:40:36

+0

@JonSkeet你当然是对的。我想我的大脑已经在周末检查出来了。 – juharr 2015-03-13 18:43:17