Sto cercando di recuperare tutti i record aggiunti oggi utilizzando la sintassi SQL DateDiff tramite l'espressione Linq in MVC 5 / Entity Framework 6. La funzione DateDiff genera un errore di runtime
In realtà voglio la seguente clausola WHERE di linq per analizzare con linq dynamics
.Where(p => DbFunctions.DiffDays(p.added_date, DateTime.Now) == 0)
al fine di recuperare i record aggiunti oggi. Esempio di codice che sto usando mostrato di seguito
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;
Riguardo alle espressioni Linq.Dynamic - come scrivere dove clausola
Usa DbFunctions
.Where(p => DbFunctions.DiffDays(p.AddedDate, DateTime.Now) == 0)
Modificare:
Se si desidera richiamare questo in modo dinamico, è necessario modificare il codice per Dynamic LINQ.
typeof(DbFunctions)
predefinedTypes
e aggiungi typeof(DbFunctions)
alla fine. Ora sarai in grado di fare questo:
.Where("DbFunctions.DiffDays(AddedDate, DateTime.Now) = 0")
E sarà tradotto in questo SQL:
WHERE 0 = (DATEDIFF (day, [Extent1].[AddedDate], SysDateTime()))
flindeberg è corretto quando dice che System.Linq.Dynamic analizza l'espressione che assegni come C #, non SQL.
Tuttavia, Entity Framework definisce la classe "DbFunctions" che consente di chiamare le funzioni sql come parte delle query di Linq.
DbFunctions.DiffDays è il metodo che stai cercando. Con questo, non è inoltre necessario utilizzare System.Linq.Dynamic.
Il tuo codice sarebbe simile a questo, penso:
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;
Se si desidera utilizzare questa funzione con System.Linq.Dynamic, sarebbe simile a questa:
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;
PERÒ! System.Linq.Dynamic non riconoscerà la classe DbFunctions e, come tale, non funzionerà immediatamente. Tuttavia, possiamo "applicare patch" a questa funzionalità utilizzando un po 'di riflessione, sebbene possa essere un po' brutta:
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 );
Eseguendo questo codice, System.Linq.Dynamic ora riconoscerà DbFunctions come un tipo che può essere utilizzato nelle espressioni C # analizzate.