ghi*_*gad 6 c# linq entity-framework entity-framework-4 entity-framework-6
我一直在使用一些LINQ over Entities,我得到了奇怪的结果,我想得到解释......
给出以下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()
};
Run Code Online (Sandbox Code Playgroud)
我得到以下SQL查询(取自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]
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.
如果我将我的LINQ查询更改为:
// Sample # 2
groupingInfo = context.AccountingTransaction.
GroupBy(a => a.Type).
Select(grp => new GroupInformation()
{
GroupName = grp.Key,
GroupCount = grp.Count()
});
Run Code Online (Sandbox Code Playgroud)
它产生完全相同的SQL查询.我感觉合理.
这是有趣的部分...如果我将我的LINQ查询更改为:
// 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()
});
Run Code Online (Sandbox Code Playgroud)
执行以下SQL(我从实际查询中删除了一些字段,但表中的所有字段(~15个字段)都包含在查询中,两次):
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
Run Code Online (Sandbox Code Playgroud)
为什么生成的SQL如此不同?毕竟,执行完全相同的代码,只是示例#3使用中间变量来完成相同的工作!
另外,如果我这样做:
Console.WriteLine(groupingInfo.ToString());
Run Code Online (Sandbox Code Playgroud)
对于示例#1和示例#2,我得到了与SQL事件探查器捕获的完全相同的查询,但对于示例#3,我得到:
System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Linq.IGrouping`2[System.Object,TestLinq.AccountingTransaction],TestLinq.GroupInformation]
Run Code Online (Sandbox Code Playgroud)
有什么不同?如果我在多个指令中拆分LINQ查询,为什么我不能获得LINQ生成的SQL查询?
ulitmate的目标是能够在运行时向查询(Where,OrderBy等)添加运算符.
顺便说一下,我在EF 4.0和EF 6.0中看到过这种行为.
谢谢您的帮助.
究其原因是因为在你的第三次尝试你指的是accounts因为IEnumerable<AccountingTransaction>这将导致使用调用查询LINQ到对象(Enumerable.GroupBy和Enumerable.Select)
另一方面,在第一次和第二次尝试中,引用AccountingTransaction保留为,IQueryable<AccountingTransaction>并且将使用Linq-To-Entities执行查询,然后Linq-To-Entities将其转换为适当的SQL语句.
| 归档时间: |
|
| 查看次数: |
207 次 |
| 最近记录: |