Как преобразовать приведенную ниже инструкцию sql group by в Linq

#linq #tsql

#linq #tsql

Вопрос:

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

Это инструкция SQL, которую я пытаюсь преобразовать

 SELECT [t5].[StatusID], [t5].[FriendlyName], sum(1) AS [Count]  
FROM (  
SELECT distinct [t0].DealID, [t0].[StatusID], [t1].[FriendlyName]  
FROM [DR_Deal] AS [t0]  
INNER JOIN [DR_DealStage] AS [t1] ON [t0].[StatusID] = [t1].[DealStageID]  
INNER JOIN [DR_Deal_ApproverInfo] AS [t2] ON [t0].[DealID] = [t2].[DealID]  
INNER JOIN [DR_Approver] AS [t3] ON [t2].[ApproverID] = ([t3].[ApproverID])  
INNER JOIN [DR_Profile] AS [t4] ON [t3].[ProfileID] = ([t4].[ProfileID])  
WHERE (LOWER([t4].[Email]) = @p0) OR (LOWER([t0].[CreatedBy]) = @p1)  
) AS [t5]  
GROUP BY [StatusID], [FriendlyName]  
ORDER BY [t5].[StatusID]
  

ПРАВКИ

да, приведенный выше sql сгенерирован с использованием linqpad, это то, что я действительно хочу преобразовать в linq

SELECT COUNT(DISTINCT [t0].DealID) AS count, [t0].[StatusID], [t1].[FriendlyName]
FROM [DR_Deal] AS [t0]
INNER JOIN [DR_DealStage] AS [t1] ON [t0].[StatusID] = [t1].[DealStageID]
INNER JOIN [DR_Deal_ApproverInfo] AS [t2] ON [t0].[DealID] = [t2].[DealID]
INNER JOIN [DR_Approver] AS [t3] ON [t2].[ApproverID] = ([t3].[ApproverID])
INNER JOIN [DR_Profile] AS [t4] ON [t3].[ProfileID] = ([t4].[ProfileID])
WHERE (LOWER([t4].[Email]) = LOWER(@Email)) OR (LOWER([t0].[CreatedBy]) = LOWER(@UserName))
GROUP BY [t0].[StatusID], [t1].[FriendlyName]
ORDER BY [t0].[StatusID]

И я думаю, что нашел решение для выполнения этого, count(distinct) используя linq, на которое я изначально наткнулся, но все равно преобразованное решение не сработало, я думаю, приведенный ниже код linq не работает, потому что я использую sql 2000, а сгенерированный sql имеет вложенные выборки, и, похоже, в sql 2000 есть некоторые ограничения. Я все еще не уверен в своих выводах, может быть, значение linq blelow вообще неверно, или может быть лучший способ написать приведенный выше sql.

 var query = (from d in DR_Deal  
join s in DR_DealStage  
on d.StatusID equals s.DealStageID  
join da in DR_Deal_ApproverInfo  
on d.DealID equals da.DealID  
join a in DR_Approver  
on da.ApproverID equals a.ApproverID  
join p in DR_Profile  
on a.ProfileID equals p.ProfileID  
where p.Email.ToLower().Equals("test@test.com")   
|| d.CreatedBy.ToLower().Equals("test")  
group d.DealID by new { d.StatusID, s.FriendlyName}  
into grp  
select new  
{  
  StatusID = grp.Key.StatusID,  
  FriendlyName = grp.Key.FriendlyName,  
  Count = grp.Distinct().Count()  
}).OrderBy(x=> x.StatusID);
  

Комментарии:

1. для меня представленный вами t-sql кажется sql, сгенерированным поставщиком linq-to-sql. С какой именно проблемой вы столкнулись.

2. Полезным инструментом, который я нашел для изучения LINQ, является LINQPad , вы можете найти его здесь www.linqpad.net

3. @nasmifive: Я согласен, это очень похоже на T-Sql, сгенерированный Linq-to-Sql

Ответ №1:

Я думаю, что есть несколько способов сделать это, но я сделал нечто подобное и сопоставил это с объектом. Эта инструкция не совсем подходит для вашей проблемы, но вы можете использовать приведенную ниже инструкцию для смешивания различных значений со значениями agregate (наличие, группировка, количество, сумма) и т.д.

              IEnumerable<MyObject> myObj                  
              =  (from d in dbContext.DR_Deal          
             /*DO ALL YOUR JOINS */ 
             join ds in dbContext.DR_DealStage on d.statusID equals ds.dealstageID
             where ds.mycolumn == myvalue

             select new MyObject()
             {
                   groupedByObject = d,
                   singleColumnsValue = ds.columnName
                   /* For calculated values have inner LINQ statements which join
                   back to elements from the main query. These can also 
                   return objects*/
                   agregateValue = (from x in dbContext.OtherTable
                                    where x.id == d.id).Count()
             })
  

Ответ №2:

Я ВСЕГДА возвращаюсь к 101 образцу LinQ

http://msdn.microsoft.com/en-us/vcsharp/aa336746