#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