将DataSet更新自动提交到数据库工具类实现

大家好!

      在项目中遇到一些要把DataSet的更改提交到数据库的需求,因此,实现了一个工具类来完成这个工作。

      设计思想:DataSet中的每一个DataTable中的每一行都有状态(RowState), 并且DataTable提供了一个GetChanges(DataRowState state)的方法来获取变化了的数据集合,返回一个新的DataTable对象。因此,我们根据数据提交的顺序,将分别处理 Insert, Update, Delete三种情况,并且根据与数据库表的映射,自动构造SQL语句,利用SqlDataAdapter完成数据提交工作。

      由于.net基础数据类型与SQL Server数据类型存在多对一的关系,且使用数据适配器(DataAdapter)时,构造SQL参数对象必须要求指定每个参数对象的长度以及更多信息(映射数据有版本的情况下),因此,不好根据DataColumn的类型来推导对应的SqlDbType,故根据需要实现了一个新的类,来保存每个列的映射及参数。

      下面是实现的原代码,有许多需要改进的地方,希望大家提出更好的意见和建议。在此谢过,先!

 

  1ExpandedBlockStart.gifContractedBlock.gif/**//* ***********************************************************************
  2InBlock.gif * Created by : Steven He [2006/02/16]
  3InBlock.gif * Descritpion: Sql Server 数据访问工具类。
  4ExpandedBlockEnd.gif * ***********************************************************************/

  5None.gifusing System;
  6None.gifusing System.Data;
  7None.gifusing System.Data.Common;
  8None.gifusing System.Data.SqlClient;
  9None.gifusing System.Text;
 10None.gif
 11None.gifnamespace Newegg.Data
 12ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 13ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// 
 14InBlock.gif    /// Summary description for SqlDbAccess.
 15ExpandedSubBlockEnd.gif    /// 

 16InBlock.gif    public class SqlDbAccess
 17ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 18InBlock.gif        static SqlDbAccess()
 19ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 20ExpandedSubBlockEnd.gif        }

 21InBlock.gif
 22ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// 
 23InBlock.gif        /// 处理传入的数据库表名,加上[],避免因表名是数据库中的关键字而出错。
 24InBlock.gif        /// 并且在不存在所有者名的时候,加上所有者名。
 25InBlock.gif        /// 
 26InBlock.gif        /// 待处理的数据库表名。
 27ExpandedSubBlockEnd.gif        /// 处理后的数据库表名。

 28InBlock.gif        private static string PrepareDbTableName(string dbTableName)
 29ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 30InBlock.gif            string[] tableName = dbTableName.Split('.');
 31InBlock.gif            if(tableName.Length == 1//只有表名
 32ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 33InBlock.gif                if(tableName[0][0== '['
 34InBlock.gif                    return tableName[0]; // [tableName] 格式
 35InBlock.gif                else 
 36InBlock.gif                    return string.Concat("dbo.[", dbTableName, "]"); //tableName 格式
 37ExpandedSubBlockEnd.gif            }

 38InBlock.gif            else
 39ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 40InBlock.gif                StringBuilder text = new StringBuilder(100);
 41InBlock.gif                for(int i=0; i<tableName.Length; i++)
 42ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
 43InBlock.gif                    if(tableName[ i][0== '['//[xx] 格式
 44InBlock.gif                        text.Append(tableName[ i][0+ '.');
 45InBlock.gif                    else // xx 格式
 46InBlock.gif                        text.Append("[" + tableName[ i] + "].");
 47ExpandedSubBlockEnd.gif                }

 48InBlock.gif                text.Remove(text.Length-11);
 49InBlock.gif
 50InBlock.gif                return text.ToString();
 51ExpandedSubBlockEnd.gif            }

 52ExpandedSubBlockEnd.gif        }

 53InBlock.gif
 54ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// 
 55InBlock.gif        /// 更新DataTable的更改到数据库中。
 56InBlock.gif        /// 并发控制采用“最后的更新生效”
 57InBlock.gif        /// 
 58InBlock.gif        /// 有效的要提交的DataTable对象
 59InBlock.gif        /// 有效的数据为连接对象
 60InBlock.gif        /// 有效的数据库表名
 61InBlock.gif        /// 有效的要提交的列及参数映射对象数组
 62InBlock.gif        /// 有效的条件列及参数映射对象数组
 63ExpandedSubBlockEnd.gif        /// 是否需要事务

 64InBlock.gif        public static void UpdateData(DataTable table, SqlConnection sqlConn, string dbTableName, 
 65InBlock.gif            ParameterColumnMapping[] dataColumnMappings, ParameterColumnMapping[] keyColumnMappings, bool needTransaction)
 66ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 67InBlock.gif            if(table == nullthrow new ArgumentNullException("table");
 68InBlock.gif            if(sqlConn == nullthrow new ArgumentNullException("sqlConn");
 69InBlock.gif            if(dbTableName == null || dbTableName.Length == 0throw new ArgumentNullException("dbTableName");
 70InBlock.gif            if(dataColumnMappings == null || dataColumnMappings.Length == 0throw new ArgumentNullException("dataColumnMappings");
 71InBlock.gif            if(keyColumnMappings == null || keyColumnMappings.Length == 0throw new ArgumentNullException("keyColumnMappings");
 72InBlock.gif            if(table.Rows.Count == 0)    return;
 73InBlock.gif
 74InBlock.gif            dbTableName = PrepareDbTableName(dbTableName);
 75InBlock.gif
 76InBlock.gif            // 设置连接是否需要在完成后关闭的标记。
 77InBlock.gif            // 如果连接对象传进来时是关闭的,则用完后也应该关闭。即保持连接传入前的状态。
 78InBlock.gif            bool connNeedClose = (sqlConn.State == ConnectionState.Closed);
 79InBlock.gif
 80InBlock.gif            SqlDataAdapter sqlAdapter = new SqlDataAdapter();
 81InBlock.gif
 82InBlock.gif            // 添加表映射及列映射
 83InBlock.gif            DataTableMapping tableMapping = sqlAdapter.TableMappings.Add(dbTableName, table.TableName);
 84InBlock.gif            for(int i=0; i<dataColumnMappings.Length; i++)
 85ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 86InBlock.gif                tableMapping.ColumnMappings.Add(dataColumnMappings[ i].SourceColumn, dataColumnMappings[ i].DataTableColumn);
 87ExpandedSubBlockEnd.gif            }

 88InBlock.gif
 89InBlock.gif            // 构造WHERE条件部分
 90InBlock.gif            StringBuilder sqlWhere = new StringBuilder(256);
 91InBlock.gif                sqlWhere = new StringBuilder(256);
 92InBlock.gif                sqlWhere.Append(" WHERE ");
 93InBlock.gif            for(int i=0; i<keyColumnMappings.Length; i++)
 94ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 95InBlock.gif                if(i == 0)
 96ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
 97InBlock.gif                    sqlWhere.Append(string.Format("[{0}] = @{0}", keyColumnMappings[ i].SourceColumn));
 98ExpandedSubBlockEnd.gif                }

 99InBlock.gif                else
100ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
101InBlock.gif                    sqlWhere.Append(string.Format(" AND [{0}] = @{0}", keyColumnMappings[ i].SourceColumn));
102ExpandedSubBlockEnd.gif                }

103ExpandedSubBlockEnd.gif            }

104InBlock.gif
105InBlock.gif            StringBuilder sqlText = new StringBuilder(1024);
106InBlock.gif            SqlTransaction sqlTran = null;
107InBlock.gif            DataTable tempTable = null;
108InBlock.gif            DataRow[] rows = new DataRow[1];
109InBlock.gif            
110InBlock.gif            // 开始提交数据
111InBlock.gif            try
112ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
113InBlock.gif                if(connNeedClose) sqlConn.Open();
114InBlock.gif
115InBlock.gif                if(needTransaction)    sqlTran = sqlConn.BeginTransaction();
116InBlock.gif                SqlCommand sqlCmd = new SqlCommand("", sqlConn, sqlTran);
117InBlock.gif
118InBlock.gif                // 处理Insert
119InBlock.gif                tempTable = table.GetChanges(DataRowState.Added);
120InBlock.gif                if(tempTable != null)
121ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
122InBlock.gif                    sqlAdapter.InsertCommand = sqlCmd;
123InBlock.gif                    StringBuilder valueText = new StringBuilder(256);
124InBlock.gif                    // 循环每一行,只处理不为Null的列
125InBlock.gif                    foreach(DataRow dr in tempTable.Rows)
126ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
127InBlock.gif                        sqlCmd.Parameters.Clear();
128InBlock.gif                        sqlText.Length = 0;
129InBlock.gif                        sqlText.Append("INSERT INTO " + dbTableName + " (");
130InBlock.gif                        for(int i=0; i<dataColumnMappings.Length; i++)
131ExpandedSubBlockStart.gifContractedSubBlock.gif                        dot.gif{
132InBlock.gif                            if(dr[dataColumnMappings[ i].DataTableColumn] != DBNull.Value)
133ExpandedSubBlockStart.gifContractedSubBlock.gif                            dot.gif{
134InBlock.gif                                sqlText.Append(string.Format(" [{0}],", dataColumnMappings[ i].SourceColumn));
135InBlock.gif                                valueText.Append(string.Format(" @{0},", dataColumnMappings[ i].SourceColumn));
136InBlock.gif                                sqlCmd.Parameters.Add(dataColumnMappings[ i].DbParameter);
137ExpandedSubBlockEnd.gif                            }

138ExpandedSubBlockEnd.gif                        }

139InBlock.gif
140InBlock.gif                        // 移除末尾的','
141InBlock.gif                        sqlText.Remove(sqlText.Length-11);
142InBlock.gif                        valueText.Remove(valueText.Length-11);
143InBlock.gif
144InBlock.gif                        // 完成Insert语句的构造并提交
145InBlock.gif                        sqlText.Append(string.Format(" ) VALUES ({0})", valueText.ToString()));
146InBlock.gif                        sqlCmd.CommandText = sqlText.ToString();
147InBlock.gif                        rows[0= dr;
148InBlock.gif                        sqlAdapter.Update(rows);
149ExpandedSubBlockEnd.gif                    }

150ExpandedSubBlockEnd.gif                }

151InBlock.gif
152InBlock.gif                // 处理Update 
153InBlock.gif                // 仅对已经发生了改变的列进行Update
154InBlock.gif                tempTable = table.GetChanges(DataRowState.Modified);
155InBlock.gif                if(tempTable != null)
156ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
157InBlock.gif                    int changedColumns = 0//用于记录已经改变的列数
158InBlock.gif                    sqlAdapter.UpdateCommand = sqlCmd;
159InBlock.gif                    foreach(DataRow dr in tempTable.Rows)
160ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
161InBlock.gif                        sqlCmd.Parameters.Clear();
162InBlock.gif                        sqlText.Length = 0;
163InBlock.gif                        sqlText.Append(string.Format("UPDATE {0} SET", dbTableName));
164InBlock.gif                        changedColumns = 0;
165InBlock.gif                        for(int i=0; i<dataColumnMappings.Length; i++)
166ExpandedSubBlockStart.gifContractedSubBlock.gif                        dot.gif{
167InBlock.gif                            // 当前版本与原始版本不等
168InBlock.gif                            if(!dr[dataColumnMappings[ i].DataTableColumn, DataRowVersion.Current].Equals(
169InBlock.gif                                dr[dataColumnMappings[ i].DataTableColumn, DataRowVersion.Original]))
170ExpandedSubBlockStart.gifContractedSubBlock.gif                            dot.gif{
171InBlock.gif                                sqlText.Append(string.Format(" [{0}]=@{0},", dataColumnMappings[ i].SourceColumn));
172InBlock.gif                                sqlCmd.Parameters.Add(dataColumnMappings[ i].DbParameter);
173InBlock.gif                                changedColumns ++;
174ExpandedSubBlockEnd.gif                            }

175InBlock.gif
176InBlock.gif                            // 仅当有列改变了才进行处理,以防止行状态改变了,但值未变的情况。
177InBlock.gif                            if(changedColumns > 0)
178ExpandedSubBlockStart.gifContractedSubBlock.gif                            dot.gif{
179InBlock.gif                                sqlText.Remove(sqlText.Length-11); //移除末尾的‘,'
180InBlock.gif                                sqlText.Append(" " + sqlWhere.ToString());
181InBlock.gif
182InBlock.gif                                // 添加条件参数
183InBlock.gif                                for(int j=0; j<keyColumnMappings.Length; j++)
184ExpandedSubBlockStart.gifContractedSubBlock.gif                                dot.gif{
185InBlock.gif                                    sqlCmd.Parameters.Add(keyColumnMappings[j].DbParameter);
186ExpandedSubBlockEnd.gif                                }

187InBlock.gif
188InBlock.gif                                // 提交数据
189InBlock.gif                                sqlCmd.CommandText = sqlText.ToString();
190InBlock.gif                                rows[0= dr;
191InBlock.gif                                sqlAdapter.Update(rows);
192ExpandedSubBlockEnd.gif                            }

193ExpandedSubBlockEnd.gif                        }

194ExpandedSubBlockEnd.gif                    }

195ExpandedSubBlockEnd.gif                }

196InBlock.gif
197InBlock.gif                // 处理Delete
198InBlock.gif                tempTable = table.GetChanges(DataRowState.Deleted);
199InBlock.gif                if(tempTable != null && tempTable.Rows.Count > 0)
200ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
201InBlock.gif                    sqlText.Length = 0;
202InBlock.gif                    sqlText.Append("DELETE FROM " + dbTableName + sqlWhere.ToString());
203InBlock.gif
204InBlock.gif                    sqlCmd.CommandText = sqlText.ToString();
205InBlock.gif                    sqlCmd.Parameters.Clear();
206InBlock.gif                    // 添加条件参数
207InBlock.gif                    for(int j=0; j<keyColumnMappings.Length; j++)
208ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
209InBlock.gif                        sqlCmd.Parameters.Add(keyColumnMappings[j].DbParameter);
210ExpandedSubBlockEnd.gif                    }

211InBlock.gif
212InBlock.gif                    sqlAdapter.DeleteCommand = sqlCmd;
213InBlock.gif                    sqlAdapter.Update(tempTable);
214ExpandedSubBlockEnd.gif                }

215InBlock.gif
216InBlock.gif                if(sqlTran != null)    sqlTran.Commit();
217ExpandedSubBlockEnd.gif            }

218InBlock.gif            catch(Exception ex)
219ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
220InBlock.gif                if(sqlTran != null)
221ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
222InBlock.gif                    sqlTran.Rollback();
223ExpandedSubBlockEnd.gif                }

224InBlock.gif                throw ex;
225ExpandedSubBlockEnd.gif            }

226InBlock.gif            finally
227ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
228InBlock.gif                if(connNeedClose)    sqlConn.Close();
229ExpandedSubBlockEnd.gif            }

230ExpandedSubBlockEnd.gif        }

231InBlock.gif
232ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// 
233InBlock.gif        /// 定义参数与列的映射关系的类。
234ExpandedSubBlockEnd.gif        /// 

235InBlock.gif        public class ParameterColumnMapping
236ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
237InBlock.gif            private string m_SourceColumn;
238InBlock.gif            private string m_DataTableColumn;
239InBlock.gif            private SqlParameter m_DbParameter;
240InBlock.gif
241ExpandedSubBlockStart.gifContractedSubBlock.gif            /**//// 
242InBlock.gif            /// 构造函数。
243InBlock.gif            /// 
244InBlock.gif            /// 数据库源列名
245InBlock.gif            /// DataTable中的列名
246ExpandedSubBlockEnd.gif            /// 对应的参数对象

247InBlock.gif            public ParameterColumnMapping(string sourceColumn, string dataTableColumn, SqlParameter dbParameter)
248ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
249InBlock.gif                m_SourceColumn = sourceColumn;
250InBlock.gif                m_DataTableColumn = dataTableColumn;
251InBlock.gif                m_DbParameter = dbParameter;
252ExpandedSubBlockEnd.gif            }

253InBlock.gif
254InBlock.gif            public ParameterColumnMapping() : this(nullnullnull)
255ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
256ExpandedSubBlockEnd.gif            }

257InBlock.gif
258ExpandedSubBlockStart.gifContractedSubBlock.gif            /**//// 
259InBlock.gif            /// 获取或设置数据库源列名。
260ExpandedSubBlockEnd.gif            /// 

261ExpandedSubBlockStart.gifContractedSubBlock.gif            public string SourceColumn dot.gif{
262ExpandedSubBlockStart.gifContractedSubBlock.gif                get dot.gif{
263InBlock.gif                    return m_SourceColumn;
264ExpandedSubBlockEnd.gif                }

265ExpandedSubBlockStart.gifContractedSubBlock.gif                set dot.gif{
266InBlock.gif                    m_SourceColumn = value;
267ExpandedSubBlockEnd.gif                }

268ExpandedSubBlockEnd.gif            }

269InBlock.gif
270ExpandedSubBlockStart.gifContractedSubBlock.gif            /**//// 
271InBlock.gif            /// 获取或设置DataTable对象中的列名。
272ExpandedSubBlockEnd.gif            /// 

273ExpandedSubBlockStart.gifContractedSubBlock.gif            public string DataTableColumn dot.gif{
274ExpandedSubBlockStart.gifContractedSubBlock.gif                get dot.gif{
275InBlock.gif                    return m_DataTableColumn;
276ExpandedSubBlockEnd.gif                }

277ExpandedSubBlockStart.gifContractedSubBlock.gif                set dot.gif{
278InBlock.gif                    m_DataTableColumn = value;
279ExpandedSubBlockEnd.gif                }

280ExpandedSubBlockEnd.gif            }

281InBlock.gif
282ExpandedSubBlockStart.gifContractedSubBlock.gif            /**//// 
283InBlock.gif            /// 获取或设置列对应的Sql参数对象。
284ExpandedSubBlockEnd.gif            /// 

285ExpandedSubBlockStart.gifContractedSubBlock.gif            public SqlParameter DbParameter dot.gif{
286ExpandedSubBlockStart.gifContractedSubBlock.gif                get dot.gif{
287InBlock.gif                    return m_DbParameter;
288ExpandedSubBlockEnd.gif                }

289ExpandedSubBlockStart.gifContractedSubBlock.gif                set dot.gif{
290InBlock.gif                    m_DbParameter = value;
291ExpandedSubBlockEnd.gif                }

292ExpandedSubBlockEnd.gif            }

293ExpandedSubBlockEnd.gif        }

294ExpandedSubBlockEnd.gif    }

295ExpandedBlockEnd.gif}

296None.gif

下面是使用示例代码:

 1None.gifSqlDbAccess.ParameterColumnMapping[] dataColumnMappings = new Newegg.Data.SqlDbAccess.ParameterColumnMapping[2];
 2None.gif                dataColumnMappings[0= new Newegg.Data.SqlDbAccess.ParameterColumnMapping("APP_ID", myData.AppSystems.AppIDColumn.ColumnName,
 3None.gif                    new SqlParameter("@APP_ID", SqlDbType.NVarChar, 20, myData.AppSystems.AppIDColumn.ColumnName));
 4None.gif                dataColumnMappings[1= new Newegg.Data.SqlDbAccess.ParameterColumnMapping("DESCRIPTION", myData.AppSystems.DescriptionColumn.ColumnName,
 5None.gif                    new SqlParameter("@DESCRIPTION", SqlDbType.NVarChar, 500, myData.AppSystems.DescriptionColumn.ColumnName));
 6None.gif
 7None.gif                SqlDbAccess.ParameterColumnMapping[] keyColumnMappings = new Newegg.Data.SqlDbAccess.ParameterColumnMapping[1];
 8None.gif                keyColumnMappings[0= new Newegg.Data.SqlDbAccess.ParameterColumnMapping("APP_ID", myData.AppSystems.AppIDColumn.ColumnName,
 9None.gif                    new SqlParameter("@APP_ID", SqlDbType.NVarChar, 20, ParameterDirection.Input, true00, myData.AppSystems.AppIDColumn.ColumnName, DataRowVersion.Original, null));
10None.gif
11None.gif                SqlConnection sqlConn = new SqlConnection(Configuration.D2WHP01_ConnString);
12None.gif                SqlDbAccess.UpdateData(myData.AppSystems, sqlConn, "AzProvider.dbo.APP", dataColumnMappings, keyColumnMappings, true);

转载于:https://www.cnblogs.com/oosnoopy/archive/2006/07/15/451507.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值