Лучший Linq2Sql эквивалент IsNull (Макс (id)) - PullRequest
4 голосов
/ 14 декабря 2009

Я хочу преобразовать следующий SQL в Linq2SQL.

select isnull(max(Id),0) from tbl

Хотя Id определен как Int NOT NULL

Я бы хотел иметь значение по умолчанию, равное 0, даже если в таблице нет строк.

Лучший читаемый подход, который мне удалось придумать, -

var maxId = dc.tbl.Select(row => row.Id)
                  .ToArray().Union(Enumerable.Range(0, 1)).Max();

Но этот подход требует сброса всех данных, более производительная, но менее читаемая версия -

var maxId = dc.tbl.Select(row => row.Id)
                  .OrderByDescending(ii => ii).FirstOrDefault();

Есть ли лучший способ?

Ответы [ 3 ]

6 голосов
/ 14 декабря 2009

Я бы использовал что-то вроде следующего.

context.Table.Max(row => (Int32?)row.Id) ?? 0

И, кстати, я думаю, что ваше второе предложение гораздо яснее о цели, чем первое.

UPDATE

Я только что проверил запрос с помощью LINQPad. Если LINQPad заставит запрос работать, а в коде его нет, ваше второе предложение, вероятно, будет лучшим решением.

context.Table
   .Select(row => row.Id)
   .OrderByDescending(id => id)
   .FirstOrDefault()

Недостатком является то, что значение по умолчанию установлено на ноль. Это можно изменить с помощью следующего запроса.

context.Table
   .Select(row => (Int32?)row.Id)
   .OrderByDescending(id => id)
   .FirstOrDefault() ?? 0

И просто отметим, что следующее не работает, поскольку LastOrDefault() не поддерживается LINQ to SQL.

context.Table
   .Select(row => row.Id)
   .OrderBy(id => id)
   .LastOrDefault()
1 голос
/ 14 декабря 2009

Может как то так?

var maxId = dc.tbl.Any() ? dc.tbl.Max(e => e.Id) : 0;

Согласно этому вопросу , вы также можете сделать что-то вроде этого:

var maxId = (from e in dc.tbl
            select (int?)e.Id).Max() ?? 0;
0 голосов
/ 14 декабря 2009

Как насчет этого:

from t in tbl
select new {
  ID = ((System.Int32?)t.ID ?? (System.Int32?)0)
}
...