"Methoden für DateTime können nicht aufgerufen werden" und andere Einschränkungen

8

Kennt jemand eine definitive Liste von LINQ to SQL-Abfrageeinschränkungen, die bei der Kompilierung nicht abgefangen werden, und (wo möglich) Workarounds für die Einschränkungen?

Die Liste, die wir bisher haben, ist:

  • Aufrufmethoden wie .Date für DateTime
    • keine Problemumgehung gefunden
  • %Code%
    • einfach, verwenden Sie stattdessen string.IsNullOrEmpty
  • %Code%
    • wir haben == "" benutzt
Richard Everett 27.11.2008, 13:02
quelle

5 Antworten

21

Im Grunde ist diese Liste riesig ... es ist alles außerhalb des relativ kleinen Satzes von Dingen werden behandelt . Leider tritt das Gesetz der undichten Abstraktionen in Kraft und jeder Anbieter hat andere Antworten ...

LINQ-to-Objects wird alles (ziemlich) tun, da es Delegaten ist; LINQ-to-SQL und Entity Framework haben verschiedene Support-Sets.

Im Allgemeinen habe ich mit den DateTime -Eigenschaften usw. ziemlich viel Erfolg gehabt - aber in Wirklichkeit müssen Sie sicherstellen, dass Ihre Abfrageausdrücke durch Unit-Tests abgedeckt werden, so dass Sie dies auch tun können Anbieter ändern (oder der Provider wird aktualisiert) Sie wissen, dass alles noch funktioniert.

Ich denke, eine Ansicht ist in TSQL zu denken; Es gibt kein BOTTOM n , aber es gibt ein TOP 1 (re das OrderByDescending ); In string.IsNullOrEmpty könnten Sie ziemlich wörtlich sein: foo.Bar == null || foo.Bar == "" ; und mit DateTime.Date kannst du wahrscheinlich ziemlich viel mit DATEPART / den verschiedenen Komponenten machen.

Eine weitere Option mit LINQ-to-SQL ist das Einkapseln der Logik in einer UDF - so könnten Sie eine UDF schreiben, die eine datetime und eine datetime zurückgibt und diese über die dbml auf den Datenkontext legt . Sie können dies dann in Ihren Abfragen verwenden:

%Vor%

Dieser Ansatz verwendet jedoch nicht unbedingt Indizes.

Aktualisierung:

  • Die unterstützten Methodenübersetzungen usw. sind hier .
  • Die unterstützten Abfrageoperationen usw. sind hier .

Für die vollständigen Details sehen Sie System.Data.Linq.SqlClient.PostBindDotNetConverter+Visitor in reflector - insbesondere die Methoden Translate... ; Einige string -Funktionen werden separat behandelt. Also keine große Auswahl - aber das ist ein Implementierungsdetail.

    
Marc Gravell 27.01.2009, 10:49
quelle
1

LINQ ist die Sprache. LINQ-to-SQL kompiliert Ihren LINQ-Befehl in eine SQL-Abfrage. Daher ist es durch die normalen Begrenzungen der TSQL-Syntax eingeschränkt, oder vielmehr durch die Elemente, die leicht in diese konvertiert werden können.

Wie andere gesagt haben, wären die Listen dessen, was Sie nicht tun können, enorm. Es ist eine viel kleinere Liste von dem, was Sie tun können. Eine allgemeine Faustregel ist, zu versuchen, zu bestimmen, wie die Funktion, die Sie verwenden möchten, in TSQL konvertiert werden würde. Wenn Sie Schwierigkeiten haben, es herauszufinden, dann verwenden Sie diese Funktion nicht (oder testen Sie sie zumindest zuerst).

Aber es gibt eine einfache Möglichkeit, LINQ-Befehle zu verwenden, die nicht in LINQ-to-SQL enthalten sind. Trennen Sie die reinen LINQ-Teile Ihres Codes von den LINQ-zu-SQL-Teilen. Mit anderen Worten, machen Sie den LINQ-to-SQL, um die Daten (mit allen Funktionen, die Sie in LINQ-to_SQL benötigen) mit dem Befehl in ein Objekt (ToEnumerable, ToList oder ähnliches) zu ziehen. Dies führt die Abfrage aus und ruft die Daten lokal ab. Jetzt ist es für die vollständige LINQ-Syntax verfügbar.

    
Carlton Jenke 27.01.2009 16:09
quelle
1

Ich habe ein Connect-Problem für String.IsNullOrEmpty () erstellt:

Feedback: Ich möchte string.IsNullOrEmpty in LINQ to SQL-Anweisungen verwenden.

Fühlen Sie sich frei, Ihre Stimme hinzuzufügen oder zu stimmen oder andere Connect-Probleme für die verschiedenen anderen Methoden zu erstellen, die in Linq to SQL nicht funktionieren. Das quietschende Rad bekommt das Fett.

    
Ryan Lundy 29.01.2009 17:49
quelle
0

Ich hatte genau dieses Problem mit DateTimes und fand heraus, dass die folgende Problemumgehung für mich funktioniert, aber mir ist klar, dass es bei größeren Resultsets zu einem Problem kommen könnte, da die Verarbeitung jetzt in meiner App statt auf der Datenbank:

%Vor%

Beachten Sie die ".ToList ()" in der Mitte - dies wirft es auf ein normales IEnumerable und erlaubt mir, die üblichen Eigenschaften zu verwenden, die ich erwarten würde.

Eine Sache, die mich immer noch leicht verwirrt, ist die Tatsache, dass dies in EF legal ist:

%Vor%

Also kann ich ".Year" oder ".Month" auf einer DateTime aufrufen, aber nicht ".Date" - ich denke, es kommt auf Typen an.

    
Zhaph - Ben Duguid 27.01.2009 12:41
quelle
0

Marc Gravells Antwort ist umfassend richtig.

Ich wollte nur dieses Detail für Date Logic (und String-Vergleiche) hinzufügen. Da Sie LinqToSql verwenden, können Sie die SqlMethods , um die Dinge zu tun, die Sie in der Datenbank tun.

    
Amy B 29.01.2009 17:43
quelle

Tags und Links