您的位置:首页 > 编程语言

ERP项目开发中的DataTable的性能优化 代码写得漂亮看起来舒服,运行起来也有效率

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

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


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }有一个临时的查询表itemTable,保存物料的计划信息。在物料计划功能中,我们会修改一下物料的计划数据,然后把它保存到数据库中。因为有很多物料,有的会被修改计划日期,有的不会修改,所以我给物料计划表itemTable加了一个额外的字段IsChanged,以表示这个物料的物料计划是否被修改过。如果被修改过,比如下面的方法

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


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }第二行代码,我会把这个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);


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }虽然这是个很小的技巧,却可以解决很多场合的问题。举例说明

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

}


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }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的列值是否被修改过相似,看似乎一点点的改进,对于系统的性能提升是有好处的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐