2015-03-13 71 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