Что заставляет работать методы SqlMethods? - PullRequest
0 голосов
/ 19 ноября 2010

Проще говоря, что заставляет метод, подобный SqlMethods.DateDiffDay, работать?

Подпись метода выглядит следующим образом:

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

Итак, что происходит внутри (или снаружи через какую-то магию), что делает эту работу:

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

... и почему скрытие этого в моем собственном методе приводит к сбою (не то, что я пытаюсь сделать это по любой причине, просто пытаюсь понять это лучше):

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

Ответы [ 2 ]

6 голосов
/ 19 ноября 2010

Очень просто: механизм анализа при просмотре дерева выражений жестко запрограммирован, чтобы определить эти методы и интерпретировать их особым образом в TSQL.На самом деле он никогда не вызывает метод - вот почему ваш MyOwnDateDiffDay терпит неудачу - он не запрограммирован на MyOwnDateDiffDay.

Вы можете сделать это для small градусов в вашем собственном коде с использованием кода [Function(...)], который обычно инкапсулирует UDF для L2S - например, вот нахальный способ обернуть встроенную функцию NEWID SQL-Server:

partial class MyDataContext
{
     [Function(Name="NEWID", IsComposable=true)] 
     public Guid Random() 
     { // to prove not used by our C# code... 
         throw new NotImplementedException(); 
     }
}
2 голосов
/ 19 ноября 2010

Использование выражения LINQ group x by y фактически вызывает (по имени) GroupBy источника. Если источник реализует IEnumerable, это будет один общий метод, который вызывается и который принимает произвольную функцию от типа источника до некоторого значения ключа:

Некоторые перечисляемые классы (такие как классы LINQ to SQL) не только реализуют IEnumerable<T>, но и IQueryable<T>. Это означает, что также доступен следующий метод:

Здесь метод получает дерево выражений , которое может быть проанализировано. В случае LINQ to SQL обнаруживается присутствие SqlMethods.*, и вместо выполнения функции он транслируется в соответствующую операцию SQL Server и выполняется на SQL Server (в вашем случае это * 1028). *).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...