ho scherzare con alcuni LINQ su soggetti e sto ottenendo risultati strani e mi piacerebbe ottenere una spiegazione ...Qual è la differenza tra questi LINQ interroga
Data la seguente query LINQ,
// Sample # 1
IEnumerable<GroupInformation> groupingInfo;
groupingInfo = from a in context.AccountingTransaction
group a by a.Type into grp
select new GroupInformation()
{
GroupName = grp.Key,
GroupCount = grp.Count()
};
ottengo la seguente query SQL (tratto da SQL Profiler):
SELECT
1 AS [C1],
[GroupBy1].[K1] AS [Type],
[GroupBy1].[A1] AS [C2]
FROM (SELECT
[Extent1].[Type] AS [K1],
COUNT(1) AS [A1]
FROM [dbo].[AccountingTransaction] AS [Extent1]
GROUP BY [Extent1].[Type]
) AS [GroupBy1]
Fin qui tutto bene.
Se cambio il mio query LINQ a:
// Sample # 2
groupingInfo = context.AccountingTransaction.
GroupBy(a => a.Type).
Select(grp => new GroupInformation()
{
GroupName = grp.Key,
GroupCount = grp.Count()
});
cede per la stessa query SQL. Ha senso per me.
Qui viene la parte interessante ... Se cambio la mia query LINQ a:
// Sample # 3
IEnumerable<AccountingTransaction> accounts;
IEnumerable<IGrouping<object, AccountingTransaction>> groups;
IEnumerable<GroupInformation> groupingInfo;
accounts = context.AccountingTransaction;
groups = accounts.GroupBy(a => a.Type);
groupingInfo = groups.Select(grp => new GroupInformation()
{
GroupName = grp.Key,
GroupCount = grp.Count()
});
viene eseguito il seguente SQL (ho messo a nudo alcuni dei campi dalla query reale, ma tutti i campi la tabella (~ 15 campi) sono stati inclusi nella query, due volte):
SELECT
[Project2].[C1] AS [C1],
[Project2].[Type] AS [Type],
[Project2].[C2] AS [C2],
[Project2].[Id] AS [Id],
[Project2].[TimeStamp] AS [TimeStamp],
-- <snip>
FROM (SELECT
[Distinct1].[Type] AS [Type],
1 AS [C1],
[Extent2].[Id] AS [Id],
[Extent2].[TimeStamp] AS [TimeStamp],
-- <snip>
CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
FROM (SELECT DISTINCT
[Extent1].[Type] AS [Type]
FROM [dbo].[AccountingTransaction] AS [Extent1]) AS [Distinct1]
LEFT OUTER JOIN [dbo].[AccountingTransaction] AS [Extent2] ON [Distinct1].[Type] = [Extent2].[Type]
) AS [Project2]
ORDER BY [Project2].[Type] ASC, [Project2].[C2] ASC
Perché gli SQL generati sono così diversi? Dopotutto, viene eseguito lo stesso codice esatto, è solo che il campione n. 3 utilizza variabili intermedie per ottenere lo stesso risultato!
Inoltre, se faccio:
Console.WriteLine(groupingInfo.ToString());
per il campione # 1 e il campione # 2, ottengo la stessa identica domanda che è stato catturato da SQL Profiler, ma per il campione # 3, ottengo:
System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Linq.IGrouping`2[System.Object,TestLinq.AccountingTransaction],TestLinq.GroupInformation]
Qual è la differenza? Perché non riesco a ottenere la query SQL generata da LINQ se divido la query LINQ in più istruzioni?
L'obiettivo ultraresistente è poter aggiungere operatori alla query (Where, OrderBy, ecc.) In fase di esecuzione.
BTW, ho visto questo comportamento in EF 4.0 e EF 6.0.
Grazie per il vostro aiuto.
Non riesco nemmeno a capire una ragione per cui qualcuno potrebbe averlo svalutato. Spiegare? – Yuck