2009-08-07 2 views
3

Учитывая следующей таблице:LINQ к SQL C# COALESCE

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, 

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

+0

Как указывали другие, LINQ и T-SQL не идентичны с точки зрения функциональности, но у меня есть вопрос для вашего SQL: почему объединение? Почему бы просто не сделать «SET @SIZES = '» перед оператором select, противоположным объединению каждой строки – John

ответ

1

Я не думаю, что LINQ к 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()); 
7

?? Попробуйте (null coalesce operator), как:

t.Length ?? 0 
+0

Используя LINQ to SQL, это создает COALESCE в результате T-SQL –

+0

На EF 6 это фактически становится 'CASE' заявление. –

0

я бы просто вернуть 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()); 
0

Вы можете использовать функцию .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, просто неявно.