LINQ to SQL C # COALESCE - PullRequest
       33

LINQ to SQL C # COALESCE

3 голосов
/ 07 августа 2009

С учетом следующей таблицы:

Length | Width | Color | ID
===========================
    18 |    18 |  blue |  1
---------------------------
    12 |    12 |   red |  1
---------------------------

Я хочу создать один столбец / строку:

 SIZES
 =================
 18 x 18, 12 x 12,

Я могу сделать это в SQL следующим образом:

DECLARE @SIZES VARCHAR(8000)
SELECT @SIZES = COALESCE(@SIZES, '') + Convert(varchar(80), [Length]) + ' x ' + 
                Convert(varchar(80), [Width]) + ', '
FROM table
where ID = 1
GROUP BY [Length], [Width]
ORDER BY [Length], [Width]
SELECT SIZES = @SIZES

Но я не могу понять, как это сделать в LINQ.

Самое близкое, что у меня было:

from t in table
where id == 1
group t by new {
                 t.Length,
                 t.Width
               } into g
orderby g.Key.Length, g.Key.Width
select new {
             SIZES = (Convert.ToInt32(g.Key.Length) + " x " +
                      Convert.ToInt32(g.Key.Width) + ", ")
           }

, который производит один столбец и две строки:

SIZES
========
18 x 18,
12 X 12,

Преобразование не имеет значения для проблемы. Столбцы определены как числа с плавающей точкой, хотя все они являются целыми числами. Ключ - функция COALESCE. Я не могу понять, как это сделать в LINQ.

Ответы [ 4 ]

9 голосов
/ 07 августа 2009

Попробуйте ?? ( оператор слияния null ) как:

t.Length ?? 0
1 голос
/ 07 августа 2009

Я не думаю, что LINQ to SQL поддерживает этот трюк T-SQL. COALESCE на самом деле не проблема (как Мехрэд указывает на то, что эквивалент в C # - ??) - это тот факт, что SQL Server объединяет каждый результат путем объединения строк в переменную @SIZES. AFAIK LINQ to SQL не может создать запрос такого типа.

Это даст желаемый результат, но конкатенация строк выполняется на вашей стороне, а не на стороне сервера SQL. Это, вероятно, не имеет значения.

var query = 
    from t in table
    where id == 1
    group t by new {
                 t.Length,
                 t.Width
               } into g
    orderby g.Key.Length, g.Key.Width
    select new {
             SIZES = (Convert.ToInt32(g.Key.Length) + " x " +
                      Convert.ToInt32(g.Key.Width) + ", ")
           };

var result = string.Join(string.Empty, query.Select(r => r.SIZES).ToArray());
0 голосов
/ 09 июня 2016

Вы можете использовать функцию .Aggregate, например, так:

(from t in table
where id == 1
group t by new {
             t.Length,
             t.Width
           } into g
orderby g.Key.Length, g.Key.Width
select new {
         SIZES = (Convert.ToInt32(g.Key.Length) + " x " +
                  Convert.ToInt32(g.Key.Width) + ", ")
       }).Aggregate((x,y) => x + y)

Это должно выкинуть одну строку, как вы хотите. Агрегат только внутренне поддерживает ту же самую переменную, которую вы определили в SQL, просто неявно.

0 голосов
/ 07 августа 2009

Я бы просто вернул int размеры из SQL и выполнил бы построение строки на стороне клиента:

var query = 
    from t in table
    where id == 1
    group t by new {
                 t.Length,
                 t.Width
               } into g
    orderby g.Key.Length, g.Key.Width
    select g.Key;

var sizeStrings = from s in query.AsEnumerable()
                  select string.Format("{0} x {1}", s.Length, s.Width);

var result = string.Join(", ", sizeStrings.ToArray());
...