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的列值是否被修改过相似,看似乎一点点的改进,对于系统的性能提升是有好处的。

posted @ 2011-12-23 17:59  信息化建设  阅读(3170)  评论(3编辑  收藏  举报