惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 三生石上(FineUI控件)
D
DataBreaches.Net
博客园_首页
J
Java Code Geeks
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
罗磊的独立博客
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog
D
Docker
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
A
About on SuperTechFans
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
MyScale Blog
MyScale Blog
G
Google Developers Blog
博客园 - 司徒正美
aimingoo的专栏
aimingoo的专栏
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 叶小钗
M
MIT News - Artificial intelligence
Recent Announcements
Recent Announcements

博客园 - J-Pei

entity framework ConnectionString include password Microsoft Visual Studio无法启动程序进行调试的解决方法 通过Process调用桌面程序 深入理解Javascript闭包(closure) 安装SQL Server 2005过程出现错误:“SQL Server 服务无法启动”的解决办法 动态修改div的xy值 asp.net mvc 与jquery应用总结 Ajax 选项 这才是真正的JQuery.ajax传递中文参数的解决方法 ASP.NET MVC生命周期介绍(转) ASP.NET页生命周期介绍:阶段,事件及其他(转) JQuery 实现网页的快捷键操作 IE8下json.js 中文编码问题 Meet Chirpy sybase性能调优 ADO.NET Entity FrameWork 4.1 RC 发布 asp.net MVC EF dynamic query 服务器返回json SQL SERVER 2008 MASTER数据库损坏修复
Entity FrameWork 4.1 RC 生成的sql语法性能存在问题
J-Pei · 2011-03-20 · via 博客园 - J-Pei

我们在用ORM框架时,框架生成的sql语法的性能是很关键的,在对EF4.1生成的sql语法进行测试时,发现存在性能问题。
测试环境vs2010 sp1 + sql server 2008 r2 + Entity FrameWork 4.1 RC

查询1
DateTime start = DateTime.Parse("2011-03-01");
DateTime end = DateTime.Parse("2011-03-31");
DataContext.Expenses.Where(a=>a.Date >= start && a.Date <= end && a.Category.Name == "2").ToList();
生成的sql
exec sp_executesql N'SELECT
[Extent1].[ExpenseId] AS [ExpenseId],
[Extent1].[Transaction] AS [Transaction],
[Extent1].[Date] AS [Date],
[Extent1].[Amount] AS [Amount],
[Extent1].[CategoryId] AS [CategoryId]
FROM  [dbo].[Expenses] AS [Extent1]
INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryId] = [Extent2].[CategoryId]
WHERE ([Extent1].[Date] >= @p__linq__0) AND ([Extent1].[Date] <= @p__linq__1) AND (N''2'' = [Extent2].[Name])',N'@p__linq__0 datetime2(7),@p__linq__1 datetime2(7)',@p__linq__0='2011-03-01 00:00:00',@p__linq__1='2011-03-31 00:00:00'

查询2
DateTime start = DateTime.Parse("2011-03-01");
DateTime end = DateTime.Parse("2011-03-31");
DataContext.Expenses.Include("Category").Where(a=>a.Date >= start && a.Date <= end && a.Category.Name == "1").ToList();
生成sql
exec sp_executesql N'SELECT
[Extent1].[ExpenseId] AS [ExpenseId],
[Extent1].[Transaction] AS [Transaction],
[Extent1].[Date] AS [Date],
[Extent1].[Amount] AS [Amount],
[Extent1].[CategoryId] AS [CategoryId],
[Extent3].[CategoryId] AS [CategoryId1],
[Extent3].[Name] AS [Name],
[Extent3].[Description] AS [Description]
FROM   [dbo].[Expenses] AS [Extent1]
INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryId] = [Extent2].[CategoryId]
LEFT OUTER JOIN [dbo].[Categories] AS [Extent3] ON [Extent1].[CategoryId] = [Extent3].[CategoryId]
WHERE ([Extent1].[Date] >= @p__linq__0) AND ([Extent1].[Date] <= @p__linq__1) AND (N''1'' = [Extent2].[Name])',N'@p__linq__0 datetime2(7),@p__linq__1 datetime2(7)',@p__linq__0='2011-03-01 00:00:00',@p__linq__1='2011-03-31 00:00:00'

查询3
Func<Expense, bool> where1 = a => a.Date >= start && a.Date <= end && a.Category.Name == "1";
DataContext.Expenses.Where(where1).ToList();

这样查询时会报错
"已有打开的与此 Command 相关联的 DataReader,必须首先将它关闭。"

查询4
Func<Expense, bool> where1 = a => a.Date >= start && a.Date <= end && a.Category.Name == "1";
DataContext.Expenses.Include("Category").Where(where1).ToList();

生成的sql
SELECT
[Extent1].[ExpenseId] AS [ExpenseId],
[Extent1].[Transaction] AS [Transaction],
[Extent1].[Date] AS [Date],
[Extent1].[Amount] AS [Amount],
[Extent1].[CategoryId] AS [CategoryId],
[Extent2].[CategoryId] AS [CategoryId1],
[Extent2].[Name] AS [Name],
[Extent2].[Description] AS [Description]
FROM  [dbo].[Expenses] AS [Extent1]
INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryId] = [Extent2].[CategoryId]

查询1、2是直接写的lambda表达式,查询4是动态生成lambda,这种方式是我们动态查询常用的,但这时他把所有的查询结果都返回了,如果是两个数据量非常大的表,这种返回是不可想象的,我感觉EF生成的sql有性能上的问题,希望听一下大家的意见,有没有解决方案。