2014-10-19 2 views
6

Ich versuche, alle Datensätze, die heute mit DateDiff SQL-Syntax über Linq-Ausdruck in MVC 5/Entity Framework 6-Anwendung hinzugefügt. DateDiff Funktion throw LaufzeitfehlerVerwenden von DateDiff mit Linq.Dynamic-Bibliothek zum Abrufen von heute Datensätze

Eigentlich i auf die folgenden Linq wollen WHERE-Klausel mit Linq Dynamik zu analysieren

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

, um heute zu holen hinzugefügten Datensätze. Beispielcode, der i unten

gezeigt verwende
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; 

In Bezug auf Linq.Dynamic Ausdrücke - wie zu schreiben, wo Klausel

Dynamic WHERE clause in LINQ

+0

Keine Eigenschaft oder ein Feld 'TAG' in Art existiert 'vsk_error_log' ... –

+0

Warum führen Sie SQL-Code für .NET-Objekte aus? –

+1

sollten Sie schließen) '" DateDiff (DAY, added_date, getdate()) = 0 "' –

Antwort

15

Verwenden DbFunctions

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

Edit:

Wenn Sie dies dynamisch aufrufen möchten, müssen Sie den Code für das dynamische LINQ ändern.

  1. Laden Sie die sample project containing DynamicLibrary.cs herunter. Die Datei befindet sich im Ordner App_Code.
  2. Suchen Sie nach der statischen Definition für predefinedTypes und fügen Sie am Ende typeof(DbFunctions) hinzu.

Jetzt werden Sie in der Lage sein, dies zu tun:

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

Und es wird auf diese SQL übersetzt werden:

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

ich möchte es in linq.Dynamic Ausdruck wie hier erwähnt http://stackoverflow.com/questions/848415/linq-dynamic-where-clause – irfanmcsd

+0

Ich versuchte, aber DiffDays ist nicht als richtige Methode erkannt. – irfanmcsd

+0

Sind Sie sicher, dass Sie anstelle des nugget-Pakets auf die heruntergeladene Datei verwiesen haben? Ich habe das Obige getestet und es funktioniert gut für mich. –

0

Ihr Code wird nie in der Datenbank ausgeführt, die „-Ausgabe "ist das Linq.Dynamic versucht, es als C# Code zu analysieren, wo es fehlschlägt. Soweit ich weiß ist es nicht möglich, SQL mit dynamic linq aufzurufen.

Ich glaube, Sie suchen ist roh SQL verwenden, nicht .NET Code, der Linq.Dynamic ist, this page at MSDN will give you more information über roh SQL verwenden.

+0

ja, aber alternativ, wie diese DbFunctions.DiffDays (p.added_date, DateTime.Now) auf Dynamik ausführen. – irfanmcsd

+0

@irfanmcsd Ihr Standort muss nicht dynamisch sein. Sie wissen, dass Sie dynamische und nicht dynamische Linq mischen können? Gibt es einen Grund, warum Sie dynamische linq verwenden? – flindeberg

+0

ich möchte eine wiederverwendbare Funktion machen, die für unbegrenzte Anzahl von Operationen verwendet werden sollte, anstatt Code für jede Operation wieder und wieder zu schreiben. Deshalb brauche ich dynamische linq Abfrage-Ansatz. – irfanmcsd

2

flindeberg ist korrekt, wenn er sagt, dass System.Linq.Dynamic den Ausdruck analysiert, den Sie als C# geben, nicht als SQL.

Entity Framework definiert jedoch die Klasse "DbFunctions", mit der Sie sql-Funktionen als Teil Ihrer Linq-Abfragen aufrufen können.

DbFunctions.DiffDays ist die Methode, die Sie suchen. Damit müssen Sie auch System.Linq.Dynamic nicht verwenden.

Ihr Code wie folgt aussehen würde, denke ich:

 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; 

Wenn Sie diese Funktion mit System.Linq verwenden möchten.Dynamisch würde es in etwa so aussehen:

 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; 

JEDOCH! System.Linq.Dynamic erkennt die Klasse DbFunctions nicht und funktioniert daher nicht ohne weiteres. Allerdings haben wir diese Funktionalität „Patch“ kann ein wenig Reflexion in Verwendung, obwohl es hässlich ein wenig sein kann:

 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); 

Durch diesen Code ausgeführt wird, wird System.Linq.Dynamic jetzt DbFunctions als eine Art erkennen, das kann in den analysierten C# -Ausdrücken verwendet werden.

+0

ja das, was ich will. Die gleiche äquivalente Funktion von DiffDays, die ich mit linq dynamic expression anstelle von direct linq verwenden musste. – irfanmcsd

+0

Ich sehe, wenn Sie dynamische Linq mit DbFunction verwenden müssen Sie ein bisschen eine Umgehungsmöglichkeit aufgrund der Art, wie System.Linq.Dynamic implementiert ist. Ich werde eine Lösung posten. –

0

Sie sollten keine SQL-Zeichenfolge ausführen müssen, wenn Sie LINQ für Entitäten verwenden. Wie andere gezeigt haben, bin ich mir nicht einmal sicher, ob es möglich ist. Die korrekte Syntax wäre so etwas wie:

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; 

Entity Framework wird dann diese in SQL kompilieren für Sie

+0

Ihre Abfrage ist hilfreich, Sie müssen sie nur mit linq dynamic expression statt normal linq erweitern. – irfanmcsd

0

-Code unten geschrieben hat mir geholfen, mein Problem behoben.

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(); 
} 

// Fetch Daten zwischen zwei Terminen dynamische Linq mit

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

können Sie die obige Methode auch mit linq verwenden: – yarg

0

// Datumsbereich (ohne Zeit)

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