2017-07-26 122 views
0

我試圖通過LINQ和Entity Framework CORE通過表進行搜索。我有2個文本框startdate和enddate,還有一個包含3個選項的單選按鈕集,包括創建,修改和兩者。在LINQ中搜索日期範圍

這是我基於谷歌的搜索和教程

 switch(radCreatedModifiedBoth) { 
      case "b": 
       if (!String.IsNullOrEmpty(startDate)) { 
        if (!String.IsNullOrEmpty(endDate)) { 
         persons = persons.Where(ps => (
                 ps.CreatedDate >= Convert.ToDateTime(startDate + " 00:00:00") && 
                 ps.CreatedDate <= Convert.ToDateTime(endDate + " 23:59:59") 
                 ) || (
                 ps.ModifiedDate >= Convert.ToDateTime(startDate + " 00:00:00") && 
                 ps.ModifiedDate <= Convert.ToDateTime(endDate + " 23:59:59") 
                 ) 
               ); 
        } else { 
         persons = persons.Where(ps => (
                 ps.CreatedDate >= Convert.ToDateTime(startDate + " 00:00:00") 
                 || 
                 ps.ModifiedDate >= Convert.ToDateTime(startDate + " 00:00:00") 
                ) 
               ); 
        } 
       } else if (!String.IsNullOrEmpty(endDate)) { 
        persons = persons.Where(ps => (
                ps.CreatedDate >= Convert.ToDateTime(endDate + " 23:59:59") 
                || 
                ps.ModifiedDate >= Convert.ToDateTime(endDate + " 23:59:59") 
               ) 
              ); 
       } 
       break; 
      case "c": 
       if (!String.IsNullOrEmpty(startDate)) { 
        if (!String.IsNullOrEmpty(endDate)) { 
         persons = persons.Where(ps => (
                 ps.CreatedDate >= Convert.ToDateTime(startDate + " 00:00:00") && 
                 ps.CreatedDate <= Convert.ToDateTime(endDate + " 23:59:59") 
                 ) 
               ); 
        } else { 
         persons = persons.Where(ps => (
                 ps.CreatedDate >= Convert.ToDateTime(startDate + " 00:00:00") 
                ) 
               ); 
        } 
       } else if (!String.IsNullOrEmpty(endDate)) { 
        persons = persons.Where(ps <= (
                ps.CreatedDate >= Convert.ToDateTime(endDate + " 23:59:59") 
               ) 
              ); 
       } 
       break; 
      case "m": 
       if (!String.IsNullOrEmpty(startDate)) { 
        if (!String.IsNullOrEmpty(endDate)) { 
         persons = persons.Where(ps => (
                 ps.ModifiedDate >= Convert.ToDateTime(startDate + " 00:00:00") && 
                 ps.ModifiedDate <= Convert.ToDateTime(endDate + " 23:59:59") 
                 ) 
               ); 
        } else { 
         persons = persons.Where(ps => (
                 ps.ModifiedDate >= Convert.ToDateTime(startDate + " 00:00:00") 
                ) 
               ); 
        } 
       } else if (!String.IsNullOrEmpty(endDate)) { 
        persons = persons.Where(ps <= (
                ps.ModifiedDate >= Convert.ToDateTime(endDate + " 23:59:59") 
               ) 
              ); 
       } 
       break; 
     } 

此代碼生成的代碼,但似乎大量低效,更不用說加入開始和結束時間到日期這樣的字符串

startDate + " 00:00:00" 
endDate + " 23:59:59" 

只是看起來不對。這是規定的方法或任何人都可以提出一個更有效的方法最好擺脫「00:00:00」 /」 23:59:59"

致謝

+0

嘗試發表在stackechange代碼審查。我不認爲你會在SO上找到你想要的。 –

+0

當你只有'endDate'倒退時,你的情況是嗎?如果你有'startDate'和'endDate'你測試過,但是如果你只有'startDate'或者'endDate',那麼你測試的更好? – NetMage

+0

謝謝,這將幫助我寫作複製和粘貼匆忙;) – Glyn

回答

1

您可以通過按測試,以簡化SQL - 條件運算符將被轉換爲SQL CASE WHEN,因爲它們不是簡單的常量。請注意,我假設您的代碼示例中有endDate測試向後。你也有很多重複的子表達式被整合到變量中。由於您使用的是EF Core,因此沒有更好的方法來處理僅限日期的比較,然後使用您正在使用的內容。在EF中,您可以使用DbFunction,但它仍然不如將日期轉換爲適當的日期+時間,以便可以使用索引。

var hasStartDate = !String.IsNullOrEmpty(startDate); 
var dtStartDate = hasStartDate ? Convert.ToDateTime(startDate + " 00:00:00") : DateTime.MinValue; 

var hasEndDate = !String.IsNullOrEmpty(endDate); 
var dtEndDate = hasEndDate ? Convert.ToDateTime(endDate + " 23:59:59") : DateTime.MinValue; 

var chkCreatedDate = (radCreatedModifiedBoth == "b" || radCreatedModifiedBoth == "c"); 
var chkModifiedDate = (radCreatedModifiedBoth == "b" || radCreatedModifiedBoth == "m"); 

persons = persons.Where(ps => (chkCreatedDate ? (hasStartDate ? ps.CreatedDate >= dtStartDate : true) && (hasEndDate ? ps.CreatedDate <= dtEndDate : true) : true) 
           || 
           (chkModifiedDate ? (hasEndDate ? ps.ModifiedDate >= dtStartDate : true) && (hasEndDate ? ps.ModifiedDate <= dtEndDate : true) : true) 
         ); 
+0

這似乎更合理,我已upvoted,但我太窮,不能顯示:) 謝謝 – Glyn