LINQ to Entity是用于查询和管理数据库的极好的ORM。 它提供了很多东西,所以必须了解它的性能。LINQ在某一些地方有它自己的坏处。 在使用Entity Framework ORM设计和查询数据库时,我们应该记住一些提示和技巧。
-
避免将所有DB对象放入一个单一实体模型中
实体模型指定了单个工作单元,而不是我们所有的数据库。如果我们有很多数据库对象没有彼此连接,或者这些(日志表,批处理进程使用的对象等)根本不被使用。因此,这些对象正在消耗内存中的空间并导致性能下降。所以尝试制作相关数据库对象的独立实体模型。
-
如果不需要,禁用实体的更改跟踪
每当您检索数据仅用于阅读目的时,不要进行修改,因此不需要对象跟踪。 因此,通过使用MergeOption禁用对象跟踪,如下所示:
1 NorthwindDataContext context = new NorthwindDataContext(); 2 context.tblCities.MergeOption = MergeOption.NoTracking;
此选项允许我们关闭对象缓存和对象不必要的标识管理。
-
使用“预生成视图”可以减少首次请求的响应时间
当ObjectContext的对象在应用程序中第一次创建时,实体框架将创建一组访问数据库所需的类。 这组类称为视图,如果您的数据模型很大,则创建视图可能会延迟Web应用程序对页面的第一个请求的响应。 我们可以通过使用T4模板或EdmGen.exe命令行工具在编译时创建视图来减少此响应时间。
-
如果不需要,避免提取所有字段
避免从数据库中获取不需要的字段。 假设我有20个字段的Customer表,我只对三个字段感兴趣,即CustomerID,Name,Address,然后只读取这三个字段,而不是提取Customer表的所有字段。
1 // 不好的实践 2 var customer = 3 (from cust 4 in dataContext.Customers 5 select cust 6 ).ToList(); 7 8 // 最佳实践 9 var customer = 10 (from cust 11 in dataContext.Customers 12 select new { 13 customer. CustomerID, 14 customer.Name, 15 customer.Address 16 }). ToList ();
-
为数据操作选择适当的集合
在LINQ我们有var,IEnumerable,IQueryable,IList类型的集合用于数据操作。每种集合对查询都有重要作用和性能影响,因此请小心使用这些集合进行数据操作。为了学习所有这些集合之间的差异,请参考文章:IEnumerable VS IQueryable , IEnumerable VS IList ,Var VS IEnumerable 。
-
在需要的地方使用编译查询
如果经常用于从数据库获取记录,则对已编译的查询进行查询。这个查询在第一次很慢,但之后它显著地提高了性能。 我们使用CompiledQuery类的编译方法进行编译查询。假设您需要基于城市一次又一次地检索客户详细信息,然后将此查询编译为已编译的查询,如:
1 // 创建实体对象 2 NorthwindEntities mobjentity = new NorthwindEntities(); 3 // 简单查询 4 IQueryable lstCus = from customer in mobjentity.tblCustomers 5 where customer.City == "Delhi" 6 select customer; 7 8 // 编译查询 9 Func> compiledQuery 10 = CompiledQuery.Compile > 11 ( 12 (ctx, city) => from customer in ctx.Customers 13 where customer.City == city 14 select customer 15 );
在上面的查询中,我们传递string类型的参数city来过滤记录。
-
仅检索所需数量的记录
当我们将数据绑定到Grid或进行分页时,仅检索所需的记录数以提高性能。 这可以通过使用Take,While和Skip方法来实现。如下所示的分页:
1 // 创建实体对象 2 NorthwindEntities mobjentity = new NorthwindEntities(); 3 int pageSize=10,startingPageIndex=2; 4 List lstCus = mobjentity.tblCustomers.Take(pageSize) 5 .Skip(startingPageIndex * pageSize) 6 .ToList();
-
避免使用Contains方法
在LINQ中,我们使用Contains方法检查数据是否存在。 但它在SQL中转换为“WHERE IN”,导致性能下降。
-
避免在数据库中使用视图
视图降低了LINQ查询性能。 它们性能较差,对LinQ性能影响很大。 所以避免在LINQ to Entities中使用视图。
-
调试和优化LINQ查询
如果要调试和优化查询,那么LINQ Pad是一个很好的工具。 对查询构造,调试和优化非常有用。
1 IQueryable lstCus = from customer in mobjentity.tblCustomers 2 where customer.City == "Delhi" 3 select customer; 4 lstCus.Dump();
LINQ Pad的Dump方法在结果窗口中提供上述查询的结果。