你要是使用datagridview然后看重他的绑定数据方便,然后还提供更新数据库啥的就用了。。那遇到问题。你会变得很蛋疼。。最近用这个东西我觉得我把BAIDU GOOGLE关于datagridview 多表 Concurrency violation(这个万恶的错误!) 外键 更新这些关键字搜出来的前4-5页全看了~结果还是没办法。。。弄得我这个周末都难过。。所以我决定 换个方式。。
其实最主要的问题就是想用用datadapter的自动update功能。。毕竟人家是微软做的么,效率肯定比自己写的要高吧~而且调人家一句UPDATE就能更新你一张表~多NB~结果呢。。恩 各种错误~恩。要总结错误~毕竟花了那么多时间~
1.datagridview
这个东西吧~有好多属性其实自己一点都不知道的。。然后就不知道咋用。。
datagridview绑定数据流程其实很简单,一个datasource=dataset就行,当然,用个bindingsource也行,因为我还有个navigator和datagridview绑定同样的东西,所以我用了个bingdingsource
当然这样绑定出来的东西也不好看~设置columns的各种属性,其中单个列直接用column【“列名”】来引用就行,hedatext、readonly之类的随便用~
DataTable dt = DataAccess.dataTable("select NAME,LEAF.ID AS ID,TYPE,WEIGHT FROM MAINSTRUCTURE,LEAF WHERE MAINSTRUCTURE.ID=LEAF.ID");
BindingSource bind = new BindingSource();
bind.DataSource = dt;
this.dataGridview1.DataSource = bind ;
this.bindingNavigator1.BindingSource = bind;
this.dataGridview1.Columns["NAME"].HeaderText = "叶节点名称";
this.dataGridview1.Columns["NAME"].ReadOnly = true;
this.dataGridview1.Columns["ID"].Visible = false;
this.dataGridview1.Columns["TYPE"].HeaderText = "类型";
this.dataGridview1.Columns["WEIGHT"].HeaderText = "权值";
datacomboboxcolumn这个东西说是能实现combobox效果。。但是我没用~用的是网上一个更好的东西~他让combobox列表面上看起来像个textbox列,但是用的时候是combobox效果~非常实用
combox cmbLeafType = new combox //这是一个简单的combox 在使用单个单元格的时候使用
this.cmboLeafType.Visible = false;
cmboLeafType.SelectedIndexChanged += new EventHandler(cmboLeafType_SelectedIndexChanged);
this.dataGridview1.Controls.Add(cmboLeafType);
//下拉菜单改变后改变datagridview中的内容
private void cmboLeafType_SelectedIndexChanged(object sender, System.EventArgs e)
{
if (((ComboBox)sender).Text == "成本型")
{
dataGridview1.CurrentCell.Value = "成本型";
}
else if (((ComboBox)sender).Text == "效益型")
{
dataGridview1.CurrentCell.Value = "效益型";
}
else
{
dataGridview1.CurrentCell.Value = "固定型";
}
}
//单击类型单元格时触发
private void dataGridview1_CurrentCellChanged(object sender, EventArgs e)
{
try
{
if (this.dataGridview1.CurrentCell.ColumnIndex == 2) //这里因为combox列在第三列
{
Rectangle rect = dataGridview1.GetCellDisplayRectangle(dataGridview1.CurrentCell.ColumnIndex, dataGridview1.CurrentCell.RowIndex, false);
cmboLeafType.Text = dataGridview1.CurrentCell.Value.ToString();
cmboLeafType.Left = rect.Left;
cmboLeafType.Top = rect.Top;
cmboLeafType.Width = rect.Width;
cmboLeafType.Height = rect.Height;
cmboLeafType.Visible = true;
}
else
{
cmboLeafType.Visible = false;
}
}
catch
{
}
}
2.用datatable保存至数据库
这个东西最头大了。。。其实ADO.NET中用datadapter 和commandbuilder可以无脑操作数据库单表。。当有跨表的选择 这个commandbuilder就2了,而且数据层的API不是我做的,同学竟然每次都要先用OPEN函数获得CONNECTION 和 COMMAND,再生成adapter,完了之后销毁。。这使我每次用adapter都是新建的。。每一个完整的。。这样更新起来也很麻烦。。先说怎么用吧~
简单的用adapter更新就是先获取
datadapter da = new datapter(conn);
adapter.fill(ds) //获得搜索的DS
然后在更新函数中用
commandbuilder cb = new commandbuilder(da); //这里commandbuilder用DA做参数生成各种SQL语句~
接着直接使用
da.update(ds);
就可以更新数据库数据与ds一样。。
以上都是单表以及无并发情况下的无脑使用。一旦遇到跨表更新之类的就恶心了。。
当然 数据库有个很好的功能叫存储过程~调用这个可以直接对任意表实现批量更新,但是当你用的数据库不支持这个你就郁闷了。。看得到摸不着啊。。。
当然.NET也想到了这个。。于是乎 人家也模拟存储过程,用自己的command让用户自己写UPDATE更新信息,反正看上去是很好用~
string sql = "update LEAFVIEW set TYPE=@TYPE,WEIGHT=@WEIGHT where ID=@ID";
OleDbDataAdapter da = new OleDbDataAdapter();
try
{
openConnection(); //这就是那个同学每次要打开数据库获得connection以及command的函数。。。
comm.CommandText = sql;
//配更新用的Command
OleDbParameter sp = new OleDbParameter();
sp = comm.Parameters.Add("@ID", OleDbType.WChar, 30);
sp.SourceColumn = "ID"; //源数据列
sp.SourceVersion = DataRowVersion.Original;
sp = comm.Parameters.Add("@TYPE", OleDbType.WChar, 30);
sp.SourceColumn = "TYPE";
sp.SourceVersion = DataRowVersion.Current;
sp = comm.Parameters.Add("@WEIGHT", OleDbType.Double);
sp.SourceColumn = "WEIGHT";
sp.SourceVersion = DataRowVersion.Current;
//把配好的cmd赋给da.UpdateCommand
da.UpdateCommand = comm;
da.Update(dt);
}
以上看上去天衣无缝~但是反正不知道为什么就是更新不成功,难道是我DT里面有个非LEAF表的列?反正以后就是无尽的concurrency violation错误。。这个错误是人家ADO.NET内部抛出的,我找死了也找不出原因,有说是要用datagridview.endinit()方法的,有的说是数据库中数据已经改掉了~dataset里面的数据不是最新的也不是最旧的具体解释参考http://msdn.microsoft.com/zh-cn/magazine/cc163924(en-us).aspx
其他concurrency violation错误参考 http://www.yesky.com/468/1771468_4.shtml
http://book.csdn.net/bookfiles/73/100732091.shtml
这篇文章对级联更新帮助蛮大~我很大一部分是参考这篇的。。
http://www.cnblogs.com/jason-xiao/archive/2009/11/29/1613326.html
多表更新。。说实话 没太看懂,而且问题跟我的不大同 于是也没仔细看~
http://blog.csdn.net/zhzuo/archive/2004/08/06/67016.aspx
http://blog.csdn.net/zhzuo/archive/2004/08/06/67037.aspx
http://blog.csdn.net/zhzuo/archive/2005/01/03/238273.aspx
OK学习就这么多~网页总算清净了~改代码去。。。