zoukankan      html  css  js  c++  java
  • ERP项目开发中的DataTable的性能优化 代码写得漂亮看起来舒服,运行起来也有效率

    公司的ERP框架是用ORM技术来访问数据库的,但有些查询还是会用DataTable保存数据,并且会把用户修改后的数据保存到服务器中。在习惯了ORM的写法后,对于用DataTable的保存用户修改过的数据,然后保存到数据库中反而有些不适应。ORM会自动检测到哪些数据项被改动了,进而生成必要的UPDATE子句,如果没有数据被更改,则不会产生任何UPDATE语句,这是ORM的好处与便利。把这个技巧应用到DataTable中,来看看下面的性能优化技巧。

    DataColumn item = new DataColumn("IsChanged", typeof(bool));
    item.DefaultValue = false;
    itemTable.Columns.Add(item);

    有一个临时的查询表itemTable,保存物料的计划信息。在物料计划功能中,我们会修改一下物料的计划数据,然后把它保存到数据库中。因为有很多物料,有的会被修改计划日期,有的不会修改,所以我给物料计划表itemTable加了一个额外的字段IsChanged,以表示这个物料的物料计划是否被修改过。如果被修改过,比如下面的方法

    itemTable.Rows[0]["PlanQty"]=200;
    itemTable.Rows[0]["IsChanged"]=true;

    第二行代码,我会把这个table的IsChange列的值设为true,表示这一行已经被修改过,在保存时,需要生成SQL UPDATE语句。这样,在窗体被关闭时或用户点击保存按钮时,用下面的判断语句

    int changed=(from item in itemTable.AsEnumerable()
                        where item.Fields<bool>("IsChanged")==true
                        selectg item).Count();
    if(changed)
    {
           foreach(item in  itemTable.AsEnumerable()
                                     where item.Fields<bool>("IsChanged")==true)
           //save item and its plan qty
    }

    changed变量判断当前是否有物料的计划数量被更改过,如果有才保存被改过的物料及其计划,否则不会做任何动作。

    以此类推,这个技巧还可以应用于删除或是新增

    DataColumn item = new DataColumn("IsNew", typeof(bool));
    item.DefaultValue = false;
    itemTable.Columns.Add(item);
    
    item = new DataColumn("IsDeleted", typeof(bool));
    item.DefaultValue = false;
    itemTable.Columns.Add(item);

    虽然这是个很小的技巧,却可以解决很多场合的问题。举例说明

    1 用户打开物料计划功能,只是看了一下,没有修改任何物料及其计划,在退出功能时,你不应该提示用户保存,因为用户没有作任何数据修改动作。

    2 用户新增加了一条物料及其计划,你可以判断是新加的,进而生产INSERT语句,而不是UPDATE语句。如果不用这个技巧,你需要到数据库中去判断是否有这个物料的计划数据,如果有则产生UPDATE语句,否则产生INSERT语句。应用我说的这个技巧(IsNew),你可以明显的减少往返于数据库之间的逻辑,性能会有明显的改善。

    3 用户删除了一条物料及其计划,itemTable少了一行,你怎么把它写回到数据库中去呢?应用这个IsDeleted技巧,不对itemTable调用DeleteRow方法,而是把它的IsDeleted设为true,表示这个物料的计划被删除了,需要产生DELETE语句发送到数据库中。

    在判断itemTable是否被修改过,也可以应用这个技巧

    foreach (DataRow row in itemTable.Rows)
    {
             if (row.RowState == DataRowState.Unchanged)
                        continue;
             //save changed item and its plan qty
    
    }

    DataRow有一个RowState属性,以表示这个表是否被修改过。你可以不用加上面的IsChanged列而应用RowState来判断,也可以达到这个目的。DataRowState.Added 表示是新增加的一行数据,其它的值是

    // Summary:
    //Gets the state of a System.Data.DataRow object.
    [Flags]
    public enum DataRowState
    {
            // Summary:
            //     The row has been created but is not part of any System.Data.DataRowCollection.
            //     A System.Data.DataRow is in this state immediately after it has been created
            //     and before it is added to a collection, or if it has been removed from a
            //     collection.
            Detached = 1,
            //
            // Summary:
            //     The row has not changed since System.Data.DataRow.AcceptChanges() was last
            //     called.
            Unchanged = 2,
            //
            // Summary:
            //     The row has been added to a System.Data.DataRowCollection, and System.Data.DataRow.AcceptChanges()
            //     has not been called.
            Added = 4,
            //
            // Summary:
            //     The row was deleted using the System.Data.DataRow.Delete() method of the
            //     System.Data.DataRow.
            Deleted = 8,
            //
            // Summary:
            //     The row has been modified and System.Data.DataRow.AcceptChanges() has not
            //     been called.
            Modified = 16,
    }
     

    对于Add或Delete的情况,我还是习惯于加IsNew或IsDeleted列,尽管这不是必要的。

    在应用ORM框架保存实体时,它会检测实体的字段属性是否被修改,只有修改过的属性,才会出现在ORM框架生成的UPDATE语句中,这样确实有效率,与判断DataTable的列值是否被修改过相似,看似乎一点点的改进,对于系统的性能提升是有好处的。

  • 相关阅读:
    sql中的不常见查询
    sql中的常见报错;
    wcf_first
    均方值-数学期望-方差
    转:模块度(Modularity)与Fast Newman算法讲解与代码实现
    转:社区发现评估指标-NMI
    转:模块度(Modularity)与Fast Newman算法讲解与代码实现
    转:聚类评价指标
    转:聚类︱python实现 六大 分群质量评估指标(兰德系数、互信息、轮廓系数)
    转:用K-Means聚类分析做客户分群
  • 原文地址:https://www.cnblogs.com/JamesLi2015/p/2299837.html
Copyright © 2011-2022 走看看