作为01年的国家高程,我十多年前做了一些软件项目,都是用Delphi平台快速开发Application项目。今天用C#.net 开发个网站式的决策系统,感觉很不适应。这种不适应性,除了界面设计的不方便性之外,还有点击事件、数据更新方法等方面。与传统的开发方法很太不一样。VS平台虽然提供很多代码自动化、代码自动检测与提示方面的功能,但我还是感觉我们软件人员还是要花很多的时间去处理应用客户端的代码(MVC模型中的V)部分,这样太浪费时间了,与传统的快速开发方法差距太大。基于VS2005的功能,我今天来介绍一下基于NewValues+DataKey的数据修改方法。先来谈一下推荐的原因吧。
用Delphi平台去开发一个面向数据库的应用程序项目很简单,学起来,几天就能学会做项目的代码。那Delphi平台为什么能做到这一点?这与Delphi平台组件中的一个核心技术(看李维出版的那本书)——Delta技术是分不开的。Delphi平台中,一个表格组件与一个存储数据的DataSet相连后,如果在表格组件中加一行数据,DataSet自动在其属性NewData中自动加一行;如果在表格组件中修改一行数据,在Dataset自动在其属性OldData和NewData自动生成相应数据(修改可看成删一行旧数据后再加一行新数据);删除也类似。然后,当更新时,DataSet根据OldData和NewData,自动生成SQL语言,更新到指定的后台DB中。我们的问题是,VS平台中的组件是否有相应的功能?我试了一下,SqlDataSource+GridView时,在不加模板字段和其他表的字段的时间,是能实现这个功能的;但是加了,好像这样好的功能丢失了。然后,我就在master.cs文件中写了下面的代码
public void updateTable(GridView gv, GridViewUpdateEventArgs e, SqlDataSource sqlDataSource, string tablename)
{
string sqlStr = "UPDATE [" + tablename + "] SET ";
foreach (System.Collections.DictionaryEntry de in e.NewValues)
{
string fieldName = de.Key.ToString();
if (isStringField(fieldName, tablename) == true)
sqlStr += "[" + fieldName + "]='" + e.NewValues[de.Key].ToString() + "', ";
else
sqlStr += "[" + fieldName + "]=" + e.NewValues[de.Key].ToString() + ", ";
}
sqlStr = sqlStr.Substring(0, sqlStr.Length - 2);
sqlStr += " WHERE ";
for (int i = 0; i < gv.DataKeyNames.Length; i++)
{
string keyName = gv.DataKeyNames[i].ToString();
if (isStringField(keyName, tablename) == true)
sqlStr += "[" + keyName + "]='" + gv.DataKeys[e.RowIndex].Values[i].ToString() + "' AND ";
else
sqlStr += "[" + keyName + "]=" + gv.DataKeys[e.RowIndex].Values[i].ToString() + " AND ";
}
sqlStr = sqlStr.Substring(0, sqlStr.Length - 4);
sqlDataSource.UpdateCommand = sqlStr;
int flag = sqlDataSource.Update();
}
protected bool isStringField(string fieldName, string tablename)
{
string sqlStr0 = "SELECT b.[name] FROM [sysobjects] a, [syscolumns] b WHERE a.[id]=b.[id] AND a.[type]='U' AND (b.[xtype] in (35,58,61,231,167)) AND a.name ='" + tablename + "'";
DataSet ds = getData(sqlStr0);
bool b = false;
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
if (fieldName == ds.Tables[0].Rows[i][0].ToString())
b = true;
}
return b;
}
}
上面就是按Delphi平台中Delta技术思路编写的程序。这些代码主要是从GridView的KeyData相关属性取表记录的Key值,从GridViewUpdateEventArgs.NewValues中,取要更新的数据(有些字段,虽然值没变,但也可放在SQL语言的Set部分中,Set其值等于原来值,这样等于没修改记录中这些字段的值)。代码中,有个 isStringField函数,是从后台SQL Server数据库系统表中到数据,判断一个字段值要不要加单引号。从工程的角度,其实上面代码还得加exception处理、要更新的字段在不在要改新的表里的判断。下面是调用上面updateTable函数的代码
protected void GridView2_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
Master.updateTable(GridView2, e, SqlDataSource3, "training_attribute");
}
调用很简单。统一的更新方法,不就是实践代码重用,达到少写代码、减少出错的目的嘛。更新、删除可参考上面代码,自己写。上面统一的更新方法,也给我们一种代码快速开发思路。我们利用SqlDataSource与GridView相连后GridView可自动获取SqlDataSource所连接的表格结构数据(通过其Select语言定义)的这样方便性,去进一步设计前端展示部分,之后采用诸如上述统一的更新方法,去增删改数据。这样可加快我们的代码工作,提高工作效率。