2014-10-19 15 views
6

我想通過Linq表達式在MVC 5/Entity Framework 6應用程序中獲取今天使用DateDiff SQL語法添加的所有記錄。 DateDiff函數拋出運行時錯誤使用DateDiff與Linq.Dynamic庫獲取今日記錄

其實我想下面的LINQ WHERE子句中使用LINQ動態

.Where(p => DbFunctions.DiffDays(p.added_date, DateTime.Now) == 0) 

今天,爲了獲取解析添加的記錄。我使用如下所示

var _list = new vsk_error_log(); 
using (var entities = new vskdbEntities()) 
{ 
    _list = entities.vsk_error_log 
    //.Where("DateDiff(DAY,added_date,getdate())=0") 
    .Where(p => DbFunctions.DiffDays(p.added_date, DateTime.Now) == 0) 
    .ToList(); 
} 
return _list; 

關於Linq.Dynamic表達式的示例代碼 - 如何寫where子句

Dynamic WHERE clause in LINQ

+0

無屬性或字段 '日' 在類型存在'vsk_error_log'... – 2014-10-19 13:00:05

+0

爲什麼你在.NET對象上運行SQL代碼? – 2014-10-19 13:01:18

+1

您應該關閉) ''DateDiff(DAY,added_date,getdate())= 0「' – 2014-10-19 13:01:33

回答

15

使用DbFunctions

.Where(p => DbFunctions.DiffDays(p.AddedDate, DateTime.Now) == 0) 

編輯:

如果你想動態調用它,你需要修改動態LINQ的代碼。

  1. 下載sample project containing DynamicLibrary.cs。該文件位於App_Code文件夾下。
  2. 找到predefinedTypes的靜態定義,並在最後添加typeof(DbFunctions)。現在

,你將能夠做到這一點:

.Where("DbFunctions.DiffDays(AddedDate, DateTime.Now) = 0") 

,它將被翻譯成該SQL:

WHERE 0 = (DATEDIFF (day, [Extent1].[AddedDate], SysDateTime())) 
+0

我想在linq.Dynamic表達式中使用它像這裏提到的http://stackoverflow.com/questions/848415/linq-dynamic-where-clause – irfanmcsd 2014-10-19 13:08:00

+0

我試過但DiffDays不被認爲是正確的方法。 – irfanmcsd 2014-10-19 22:01:52

+0

你確定你正在引用你下載的文件而不是nuget包嗎?我已經測試過以上,它對我來說工作得很好。 – 2014-10-19 22:03:06

0

你的代碼是從來沒有在數據庫中執行,該「問題「是Linq.Dynamic試圖解析它爲C#代碼,它在哪裏失敗。據我所知,不可能用動態LINQ調用SQL

我相信你正在尋找的是使用原始SQL,不.NET代碼Linq.Dynamic是,this page at MSDN will give you more information關於使用原始SQL

+0

是的,但也可以選擇如何執行此動態DbFunctions.DiffDays(p.added_date,DateTime.Now)。 – irfanmcsd 2014-10-19 13:46:12

+0

@irfanmcsd你的位置不需要動態。你知道你可以混合動態和非動態linq?你有使用動態LINQ的原因嗎? – flindeberg 2014-10-19 14:37:01

+0

我想做一個可重複使用的函數,應該用於無限次的操作,而不是一次又一次地爲每個操作編寫代碼。這就是爲什麼我需要動態LINQ查詢方法。 – irfanmcsd 2014-10-19 18:38:22

2

flindeberg是正確的,當他說System.Linq.Dynamic分析表達式,你給的C#,而不是SQL。

但是,實體框架定義了類「DbFunctions」,它允許您調用SQL函數作爲Linq查詢的一部分。

DbFunctions.DiffDays是您正在查找的方法。有了這個,你也不需要使用System.Linq.Dynamic。

您的代碼將是這個樣子,我想:

 var _list = new vsk_error_log(); 
    using (var entities = new vskdbEntities()) 
    { 
     _list = entities.vsk_error_log 
      .Where(entry => DbFunctions.DiffDays(entry.added_date, DateTime.UtcNow) == 0) 
      .ToList(); 
    } 
    return _list; 

如果你想使用System.Linq的這個功能。動態的,它看起來像這樣:

 var _list = new vsk_error_log(); 
    using (var entities = new vskdbEntities()) 
    { 
     _list = entities.vsk_error_log 
      .Where("DbFunctions.DiffDays(added_date, DateTime.UtcNow) == 0") 
      .ToList(); 
    } 
    return _list; 

然而! System.Linq.Dynamic將無法識別類DbFunctions,因此,這不會開箱即用。但是,我們可以「打補丁」,在使用位反映的這個功能,雖然它可以是一個有點難看:

 var type = typeof(DynamicQueryable).Assembly.GetType("System.Linq.Dynamic.ExpressionParser"); 

    FieldInfo field = type.GetField("predefinedTypes", BindingFlags.Static | BindingFlags.NonPublic); 

    Type[] predefinedTypes = (Type[])field.GetValue(null); 

    Array.Resize(ref predefinedTypes, predefinedTypes.Length + 1); 
    predefinedTypes[ predefinedTypes.Length - 1 ] = typeof(DbFunctions); 

    field.SetValue(null, predefinedTypes); 

通過運行該代碼,System.Linq.Dynamic現在認識DbFunctions的類型,可以在解析的C#表達式中使用。

+0

是的,這是我想要的。相同的DiffDays等價函數,我需要使用linq動態表達式而不是直接linq。 – irfanmcsd 2014-10-19 20:33:31

+0

我看到,如果您需要使用動態LINQ和DbFunction,則由於System.Linq.Dynamic的實現方式,您需要使用一點變通方法。我會發布解決方案。 – 2014-10-20 06:30:42

0

當您使用LINQ to Entity時,您不需要運行SQL字符串。正如其他人所指出的,我甚至不確定這是否可能。正確的語法會是這樣的:

var _list = new List<vsk_error_log>(); 
using (var entities = new vskdbEntities()) 
{ 
    _list = entities.vsk_error_log 
    .Where(log => log.added_date >= DateTime.Now.AddDays(-1)) 
    .ToList(); 
} 
return _list; 

實體框架將隨後編譯成SQL這個給你

+0

你的查詢很有幫助,只需要用linq動態表達式而不是普通的linq來擴展它。 – irfanmcsd 2014-10-19 20:34:24

0

代碼貼在下面幫我固定我的問題。

var _list = new List<vsk_error_log>(); 
using (var entities = new vskdbEntities()) 
{ 
    _list = entities.vsk_error_log 
     .Where("added_date >= @0", DateTime.Now.AddDays(-1)) 
     .OrderBy(entity.Order) 
     .Skip(entity.PageSize * (entity.PageNumber - 1)) 
     .Take(entity.PageSize) 
     .ToList(); 
} 

//使用動態LINQ抓取兩個日期之間的數據

.Where("added_date >= @0 AND added_date < @1", DateTime.Now.AddDays(-7), DateTime.Now); 
+0

你可以用linq上面的方法: – yarg 2016-06-05 09:52:18

0

//指定日期範圍(無時間)

DateTime currentDate = System.DateTime.Now.Date; 
    query = query.Where(p => p.added_date == currentDate);