2017-02-15 2 views
1

У меня есть следующие SQL заявлениеКак преобразовать этот SQL-запрос в запрос LINQ?

SELECT D.*, COALESCE(T_DIZ.adet, 0) AS DIZ, COALESCE(T_OMU.adet, 0) as OMUZ 
FROM 

(SELECT A.DOK,COUNT(DISTINCT GNL) AS toplam FROM CKS A GROUP BY A.DOK) AS D 

LEFT OUTER JOIN (
    SELECT DOK, ATUR,count(DISTINCT HST)as Adet, COUNT(DISTINCT GNL) AS adet FROM CKS 
    WHERE ATUR LIKE '%DIZ%' 
    GROUP BY DOK, ATUR 
) T_DIZ ON(T_DIZ.DOK = D.DOK) 

LEFT OUTER JOIN (
    SELECT DOK, ATUR,count(DISTINCT HST)as Adet, COUNT(DISTINCT GNL) AS adet FROM CKS 
    WHERE ATUR LIKE '%OMU%' 
    GROUP BY DOK, ATUR 
) T_OMU ON(T_OMU.DOK = D.DOK) 

Этот запрос такой же результат

SELECT DISTINCT(DOK), (COUNT(DISTINCT GNL)) AS TOP, 
(CASE WHEN ATUR LIKE '%DIZ%' THEN COUNT(DISTINCT GNL) ELSE 0 END) AS DIZ, 
(CASE WHEN ATUR LIKE '%OMU%' THEN COUNT(DISTINCT GNL) ELSE 0 END) AS OMU 
FROM S_GC_UST 
WHERE GC = 'C' 
GROUP BY DOK, ATUR, TRH 

Может кто-нибудь, пожалуйста, помогите мне, чтобы преобразовать это заявление LINQ?

спасибо.

+0

Сколько записей будет запрошено? –

+0

Приблизительно 400 записей. –

+0

Вы знаете, что есть лучший способ написать этот SQL, чтобы он был в 3 раза (по крайней мере) быстрее? Поскольку вам не нужно использовать подзапросы. – Hogan

ответ

-1

Простой ответ заключается в том, что вы не выполняете, по крайней мере, по-своему, предполагая, что вы используете Entity Framework или аналогичный ORM.

This post описывает, как обрабатывать подзапросы в LINQ. Насколько мне известно, в «семантической» LINQ возможности нет. Проблема с предложенным в этой статье методом заключается в том, что подзапросы не выполняются вместе с основным запросом, а производительность - это кошмар.

Я всегда обрабатывал эту ситуацию, записывая хранимую процедуру в T-SQL и сопоставляя ее через EF.

+0

Использовать представления не procs. Мнения являются составными ... procs нет. –

+1

Проблема с этим ответом, который не является ответом, заключается в том, что он игнорирует тот факт, что исходный SQL может быть легко реорганизован, чтобы не иметь подзапросов. Это легко переписать в linq. – Hogan

0

Ваш запрос sql действительно очень сложный, что я не могу дать вам целое решение. Я должен был дать вам некоторую идею разбить этот сложный SQL-запрос на небольшой, который можно легко обрабатывать.
У вас есть три части, я упростил их как D, T_DIZ, T_OMU. И тогда я должен их упростить отдельно. И вы должны лучше рассмотреть Groupby, Coalesce, LEFT OUTER JOIN после того, как у вас будет схематическое изображение запроса. Соответственно, у нас есть три запроса: query1, query2, query3.

qurey1 = from a in CKS Group a by Key DOK into Group 
     select DOK = Group.DOK, 
       TOPLAM = Group.Select(x => x.GNL).Distinct().Count() 

query2 = from b in CKS 
     where SqlMethods.Like(b.ATUR, "%DIZ%") 
     Group b by new Key {DOK, ATUR } into Group 
     select DOK = Group.DOK, 
       ATUR = Group.ATUR, 
       Adet = Group.Select(x => x.HST).Distinct().Count(), 
       adet = Group.Select(x => x.GNL).Distinct().Count() 

//the same way of query2, you can get query3. 

//Then you can use a query23 to unit all of query2 and query3 
query23 = (from x in query2 select new {DIZ= x.A, OMUZ = 0}) 
      .Concat(from y in query3 select new {DIZ = 0, DIZ = y.B}); 

//At last, you can put query1 and query23 together. 
query123 = from e in query1 
      join f in query23 
      on e.DOK equals f.DOK 
      into query 
      from g in query.DefaultIfEmpty() 
      select new { toplam = g.toplam , 
         DIZ= g==null ? 0:g.DIZ , 
         OMUZ = g==null?0:g.OMUZ }; 

//and then 
var result = query123.ToList(). 

В решении по-прежнему есть небольшой недостаток. Надеюсь, это будет полезно для вас.

+0

Вместо SqlMethods.Like (b.ATUR, «% DIZ%») вы можете использовать b.ATUR.Contains («DIZ»). И эквивалент Coalesce = ??. Итак, DIZ = g == null? 0: g.DIZ переводит к DIZ = g? .DIZ ?? 0. –

+0

Да, вы сделали хорошее предложение. –

Смежные вопросы