2010-11-18 8 views
0

Einfach gesagt, was macht eine Methode wie SqlMethods.DateDiffDay funktioniert?Was macht "SqlMethods" -Methoden?

Die Signatur der Methode sieht wie folgt aus:

public static int DateDiffDay(DateTime startDate, DateTime endDate); 

Also, was im Inneren vor sich geht (oder außerhalb über einige Magie) das macht diese Arbeit:

var query = from a in db.TableA 
      group a by SqlMethods.DateDiffDay(a.Start, a.End) into g 
      select g.Key; 

... und warum sollte es versteckt innerhalb meiner eigenen Methode mache es scheitern (nicht, dass ich versuche, dies aus irgendeinem Grund zu tun, nur zu versuchen, es besser zu verstehen):

var query = from a in db.TableA 
      group a by MyOwnDateDiffDay(DateTime startDate, DateTime endDate) into g 
      select g.Key; 

public static int MyOwnDateDiffDay(DateTime startDate, DateTime endDate) 
{ 
    return SqlMethods.DateDiffDay(startDate, endDate); 
} 

Antwort

6

Ganz einfach: Die Parsing-Engine ist, wenn man den Ausdrucksbaum betrachtet, fest programmiert, um diese Methoden zu erkennen und sie in TSQL in einer bestimmten Weise zu interpretieren. Es nie tatsächlich Anrufe die Methode - weshalb Ihr MyOwnDateDiffDay schlägt fehl - es ist nicht programmiert, um MyOwnDateDiffDay Spot.

Sie können dies tun, um einen kleinen Grad in Ihrem eigenen Code durch den [Function(...)] Code, der normalerweise UDF für L2S kapselt - zum Beispiel, hier ist eine freche Art und Weise der Einwickeln der NEWID eingebauten SQL-Server-Funktion:

partial class MyDataContext 
{ 
    [Function(Name="NEWID", IsComposable=true)] 
    public Guid Random() 
    { // to prove not used by our C# code... 
     throw new NotImplementedException(); 
    } 
} 
+0

Ja, ich suchte nach Hinweisen für eine sauberere Möglichkeit, die UDF-Lösung zu ersetzen. Ich hatte gehofft, dass dies nicht die Antwort sein würde, aber gleichzeitig erwartete ich es auch. Danke für die Antwort! – Ocelot20

2

Die Verwendung des LINQ-Ausdrucks group x by y ruft tatsächlich (nach Name) GroupBy auf der Quelle. Wenn die Quelle IEnumerable implementiert, wäre dies eine gängige Methode, die aufgerufen wird, und die aus dem Quelltyp zu einem gewissen Schlüsselwert für eine beliebige Funktion übernimmt:

Einige enumerable Klassen (wie die LINQ to SQL-Klassen) implementieren nicht nur IEnumerable<T>, sondern auch IQueryable<T>. Dies bedeutet, dass das folgende Verfahren verfügbar:

Hier wird das Verfahren ein expression tree empfängt, das analysiert werden kann. Im Fall von LINQ to SQL wird das Vorhandensein von SqlMethods.* erkannt und, anstatt die Funktion auszuführen, wird es in die entsprechende SQL Server-Operation übersetzt und auf dem SQL Server ausgeführt (in Ihrem Fall ist es DATEDIFF).