zoukankan      html  css  js  c++  java
  • 如何提高LINQtoSQL延时加载的性能

    对于数据上下文DataContext来说,它有一个属性叫做DeferredLoadingEnabled,它的默认值为true,意思是开启模型的延时加载功能,例如:当你有一个对象Order_info,它有关系表Order_Detail,它们之间为一对多的关系,这在dbml模型中用EntitySet<T>来表示,意为实体的集合。而开启模型的延时加载功能时,只要你查询出Order_Info后,如果在前台使用到了Order_Detail,系统就会将Order_Detail的相关数据也查询出来,听上去不错,看代码:

    复制代码
    @foreach (var item in Model)
    { 
        <p>
            @item.OrderID
            @item.CreateDate
        </p>
       if (item.Order_Detail.Count > 0)
       {
           foreach (var detail in item.Order_Detail)
           { 
        <p style="margin: 10px;">@detail.OrderID @detail.ProductName</p>
           }
       }
    }
    复制代码

    产生的SQL代码:

    注意,当前台对Order_Detail有需要时,系统会产生查询Order_Detail的代码,如果你的10条Order_Info记录,那么,系统会向SQLSERVER发送10条语句
    ,这让我们感觉到了一点坏味道,没错,使用延时加载不但没有提高性能,反尔加大了数据库的交互,事实上,我可能不是微软的本意,可能是我们误会了DeferredLoadingEnabled的用意,呵呵!

    DeferredLoadingEnabled使用场合:对于单条记录可以使用,对于集合对象不应该使用它

    Linq To Sql对于集合对象的导航属性进行延时加载,提供了自己的解决方案

    小插曲,一般我们建立DBML模型后,如果希望改它的代码部分我们一般不会在原文件上改,因为重新生成数据模型后,你改的代码就被覆盖了,而我们的做法是新建一个类文件,它与DBML模型文件的数据上下文对象同名(微软为我们建立的上下文类是partial的,人家已经为咱们预留出接口了,呵呵),如果希望在数据上下文被建立时执行代码,可以在分部方法OnCreate里作文章(注意默认构造方法已经被原类占用,所以你的分部类不能再定义一个空构造方法了,呵呵)。

    DataLoadOptions 对象为我们提供了立即加载模式(饥饿加载),它所产生的SQL语句是我们可以接受的,但它不会按需查询了,即将order_info和order_detail进行join

    查询并直接返回数据,呵呵。

    这种方法只在分部方法OnCreate中定义即可,你的DAL实现层,BLL业务组合层,WEB展现层的代码都不用调整,呵呵。

    复制代码
         partial void OnCreated()
            {
                // this.DeferredLoadingEnabled = false;//关闭延时加载
                #region 优化后的延时加载,对某个对象进行延时加载
                DataLoadOptions dl = new DataLoadOptions();
                dl.LoadWith<Order_Info>(p => p.Order_Detail);
                this.LoadOptions = dl;
                #endregion
    
            }
    复制代码

    而这种立即加载所产生的SQL语句是我们可以接受的,看图:

    它解释成的SQL语句也是我们熟悉的,看代码:

    复制代码
    SELECT [t0].[OrderID], [t0].[UserID], [t0].[CreateDate], [t1].[OrderDetailID], [t1].[OrderID] AS [OrderID2], [t1].[ProductID], [t1].[ProductName], (
        SELECT COUNT(*)
        FROM [dbo].[Order_Detail] AS [t2]
        WHERE [t2].[OrderID] = [t0].[OrderID]
        ) AS [value]
    FROM [dbo].[Order_Info] AS [t0]
    LEFT OUTER JOIN [dbo].[Order_Detail] AS [t1] ON [t1].[OrderID] = [t0].[OrderID]
    ORDER BY [t0].[OrderID], [t1].[OrderDetailID]
    复制代码

    恩,看来linq to sql知所以性能低下,不是它本身的问题,而是我们对它不够了解呀,呵呵!

  • 相关阅读:
    jQuery 核心
    Js实现内容向上无缝循环滚动
    浅析CSS postion属性值用法
    JS原生Ajax请求
    详解SQL集合运算
    Windows上开启IIS
    poj 4618 暴力
    hdu 4614 线段树
    poj 3468 线段树
    hdu 1698 线段树成段更新
  • 原文地址:https://www.cnblogs.com/cw_volcano/p/2981499.html
Copyright © 2011-2022 走看看