>
xml地图|网站地图|网站标签 [设为首页] [加入收藏]

x6163银河官方网站在调用者rdr.close()时会自动关闭

- 编辑:银河至尊官网网址 -

x6163银河官方网站在调用者rdr.close()时会自动关闭

1.CommandBehavior类
这个类与Sqldataread相关,比如:
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
这个rdr是一般是要返回外调用者,那他调用完后怎么去关闭数据库连接呢?如果象上面这样写,在调用者rdr.close()时会自动关闭数据库,省事省心啊

UpdateCommand和DeleteCommand出现DBConcurrencyException异常。调试提示:违反并发性: DeleteCommand 影响了预期 1 条记录中的 0 条;或   违反并发性: UpdateCommand影响了预期 1 条记录中的 0 条。

Select()能从数据集中选择出特定的数据子集,结果是DataRow[],括号内参数与sql的where子句写法一样,如:DataTable.Select("id>5")  

在插入、更新或删除操作过程中当受影响的行数等于零时由 DataAdapter 引发的异常。

5.DataSet.GetChange/DataTable.GetChange,DataSet.Merge/DataTable.Merge,DataTable.Select方法
GetChange()能从数据集中选择出与数据集初始状态发生了变化的数据行,返回一个数据子集,是跟据DataViewRowState来进行判断的
Merge()能将数据集合并,如果对象是DataTable/DataRow[],默认合并进DataSet.Table[0],如果对象是DataSet,则第0个合并进第0个,第1个合并进第1个,以此类推,它是跟据主键来判断与合并的
有个比较好的文章:

本文转载:

4.DataSet.AcceptChanges 方法与 SqlDataAdapter.Update
DataSet.AcceptChanges只是在内存在对数据向DataSet提交
SqlDataAdapter.Update才是真正将变化反映到数据库中了
Update要用在AcceptChanges之前,因为使用数据集的数据操作方式是断开与数据库连接的,也就是说只是在得到数据库数据的副本后立即断开了与数据库的连接。你无法保证你的数据是最新的(你不知道是否其他用户在你FILL后是否有修改了数据),所以update也不一定成功。即便成功了,你也没有刷新数据,你仍然不能得到最新的数据。如果你先acceptchange,那么这些行的状态就改变了,这样他们将不能得到更新,因为update方法是根据行的状态进行更新的。你在update成功后acceptchange只能保证你现有的能看到的数据是正确的(这也是暂时的和不确定的)。
所以:
当调用   Datatable.AcceptChanges后再调用Adapter.Update将不会有记录更新到服务器中的记录了,因为调用Datatable.AcceptChanges所有行DataRowState也会随之更改:所有状态为Added和Modified的行的状态都变为Unchanged;状态为Deleted的行则被移除
反过来如果Adapter.Update后如果不调用Datatable.AcceptChanges,那么所有行DataRowState不会有什么更改,下次如果再调用Adapter.Update还会有与上次Adapter.Update相同记录更新到数据库中。
Adapter.Update 会自动调用dataset的AcceptChanges
还有两个属性:
AcceptChangesDuringFill和
AcceptChangesDuringUpdate,这个属性默认值为true,就实现了上面所说的自动调用

可能的解决方法:

这时ds.Tables[0].TableName为orders,ds.Tables[1].TableName为employees;这样就方便了按句子取一个表,比如DataTable orders=ds.Tables["orders"];
需要说明的是"Table","Table1"...是固定的名称,不可乱写哈!

这里的违反并发性:不是指多人编辑引起的并发。

2.DataAdapter.TableMappings 属性
如果一个DataAdapter返回的是多个记录集,默认的情况下,Fill(DataSet ds)后ds中的第一个表名是Table,第二个表是Table1,第三个是Table2。如果用了TableMappings,那么这些Table,Table1,Table2就可以用TableMappings中指定的名称了。比如:
sqlAda = new SqlDataAdapter();
sqlAda.TableMappings.Add("Table", "orders");
sqlAda.TableMappings.Add("Table1", "employees");
...
ds = new DataSet();
sqlAda.Fill(ds);

1 检查是否设有主键。

3.SqlDataAdapter.Update方法
这里用的是ado.net的断开模式,就是说所有的数据更改在dataset中完成,然后一次性提交到数据库中
首先要这样做:
SqlConnection con = new SqlConnection(@"server=.ljzforever;database=test;uid=sa;pwd=ljz");
SqlDataAdapter dap=new SqlDataAdapter("select * from a", con);SqlCommandBuilder scb = new SqlCommandBuilder(dap);
用SqlCommandBuilder将SqlDataAdapter打包一下,其实你提交回数据库的时候,本质提交的还是用Sql脚本,这个类的作用是对比dataset与数据库中的数据,当数据不一致的时候自动将改动的地方自动生成sql脚本提交,而不用自手动来写
dap.Fill(ds);
这样数据库进Dataset了
当dataset中的数据有更改时,比如加了一行
ds.Tables[0].Rows.Add("111", "zzz");
你需要把数据提交数据库,真正的增加一行,就要这样:
dap.Update(ds);
这行的意思是提交,这样,内存中改动的部份就真正反映到数据库中了

语句导致。

也反应这样处理:

?


应该在RowUpdating事件里面处理一下,如果有并发行出现,就跳过 e.Status = UpdateStatus.Continue;

 

状态 说明
Continue 继续执行更新操作。
ErrorsOccurred 中止更新操作并引发异常。
SkipCurrentRow 忽略当前行并继续执行更新操作。
SkipAllRemainingRows 中止更新操作但不引发异常。

我们建议目前这样处理:
if(this.工资管理DataSet.职工基本信息.GetChanges!=null)
{Me.职工基本信息TableAdapter.Update(Me.工资管理DataSet.职工基本信息.GetChanges)}

 

 

 

 private void Form1_Load(object sender, EventArgs e)
        {
            string conn = "Data Source=.;Initial Catalog=TestDB;Integrated Security = SSPI;";
            using (SqlConnection connection = new SqlConnection(conn))
            {
                connection.Open();
                string select = "SELECT * FROM Table_1";
                SqlDataAdapter da = new SqlDataAdapter(select, connection);
                da.RowUpdating += new SqlRowUpdatingEventHandler(da_RowUpdating);
                DataSet ds = new DataSet();
                da.Fill(ds);
                DataTable dataTable = ds.Tables[0];

                dataTable.Rows[0][1] = "9999";
                // 删除第8行
                //dataTable.Rows[1].Delete();

                SqlCommand cmd = new SqlCommand();
                SqlCommandBuilder objCommandBuilder = new SqlCommandBuilder(da);
                cmd=objCommandBuilder.GetDeleteCommand();
                da.Update(dataTable);
x6163银河官方网站在调用者rdr.close()时会自动关闭数据库,违反并发性。                //if (dataTable.GetChanges() != null)
                //{
                //    da.Update(dataTable.GetChanges());
                //}

                //dataTable.AcceptChanges();

                this.dataGridView1.DataSource = dataTable;

            }
        }

        void da_RowUpdating(object sender, SqlRowUpdatingEventArgs e)
        {
            e.Status = UpdateStatus.Continue;
        }

 

         

 

问题原因:

   UpdateCommand的问题:检查更新的字段的原始值是否为空值(原始空值更新时可能会引发此异常)。

3、多人并行操作也可能引发这样的异常。

如果你采用了BindingSource和TableAdapter的话,请参考下面的代码:


例程来源:人民邮电出版社出版的书《Visual Basic .NET 2005数据库编程技术与实例》

详情请见:


Me.Validate()

Me.职工基本信息BindingSource.EndEdit()

Me.职工基本信息TableAdapter.Update(Me.工资管理DataSet.职工基本信息.GetChanges)

Me.工资管理DataSet.职工基本信息.AcceptChanges()
但是这样做后,导致了,dataset和数据库不一致的问题。是.AcceptChanges()

2 DeleteCommand的问题:检查是否含有自动编号字段(Access的自动编号字段可能会引发此异常);

本文由技术交流发布,转载请注明来源:x6163银河官方网站在调用者rdr.close()时会自动关闭