C#操作数据集更新到数据库的问题

yuhan1573 2009-04-28 04:06:15
大致代码如下:

MySqlDataAdapter dadest = new MySqlDataAdapter();//数据适配器

DataSet dataset = new DataSet();

dadest.SelectCommand = new MySqlCommand("SELECT * FROM " +“tablename”, conn);
dadest.MissingSchemaAction = MissingSchemaAction.AddWithKey;

//ExecuteFunction("alter table "+tablename+" AUTO_INCREMENT=1");
//CommandBuilder为自动生成SQL语句,配合DataAdapter使用
MySqlCommandBuilder mysqlcommbuild = new MySqlCommandBuilder(dadest);
dadest.Fill(dataset,“tablename”); //获取表内容填充到数据集中

DataRow newrow = dataset.Tables[tablename].NewRow();//目的表中新行

newrow["ID"] = 10; //赋值
newrow["name"] = "郁闷";

dataset.Tables["tablename"].Rows.Add(newrow); //添加进数据集

dadest.Update(dataset,tablename); //提交更新

问题是:其中ID列为主键,auto_increment属性。原表中已有五列数据ID:1-5.
如上面所示,我想新添加进ID为10的项,但结果确是ID为6。请大侠们解释并指点下!谢谢
...全文
841 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
SailorXing 2010-08-09
  • 打赏
  • 举报
回复
楼主脑子有毛病~
sushou2009 2009-04-30
  • 打赏
  • 举报
回复
貌似自动增长列是不能填入数据的~
llsen 2009-04-30
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yuhan1573 的回复:]
引用 1 楼 zgke 的回复:
ID是自动增长字段把.


很感谢关注,但是这样连问题都没看清,就抛出来个有技巧性的推测,小弟是在不敢恭维。。
[/Quote]

大佬你也敢怀疑
真佩服你的勇气

你的问题就是由于这个原因导致的
大佬问题看清了
llsen 2009-04-30
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 yangqidong 的回复:]
引用 13 楼 yuhan1573 的回复:
引用 12 楼 yangqidong 的回复:

SqlDataAdapter在做数据插入的时候,根本不会用到ID,所以你的行ID只是多少,根本就不会理会的
正如zgke所说的,你可以启用自增列插入的功能


谢谢你的指点,这个自增列插入功能是什么?能具体点不?

IDENTITY_INSERT 意思就是,是自动增长的,但却又是可以插入的
[/Quote]

自增就是你不用管他,他是自己加的,你赋值也没用
Insert into 时候不用加id这列就ok
yuhan1573 2009-04-30
  • 打赏
  • 举报
回复
数据库用的是Mysql....
lijianqiang 2009-04-30
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 jerrylyj 的回复:]
Sql Server里面自增是不能修改的,access好像可以
[/Quote]


你应该先学数据库 看来表不是你自己建的 自增字段 把标识设置成"否"
leiziaitudou 2009-04-30
  • 打赏
  • 举报
回复
看哈ID的描述////
yuhan1573 2009-04-30
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 zhzuo 的回复:]
回楼主,你的设计本身就是有矛盾的呀,可能过一段时间您会意识到这一点。
[/Quote]

只有走过了才知道路通不通,很感谢你的关注与指点。
现在对这个问题做下总结吧:
对于自动增长列:
1.直接使用SQL语句指定插入ID,只要指定ID不与表中已有项ID重复就可插入成功。
2.使用DataAdapter数据适配器配合CommondBuilder命令自动编辑器,自动生成的插入语句将忽略指定ID,采用自增长赋值。
3.这个问题我没有找到解决的办法,还是自己动手写插入语句完成的。

虽然没有解决,还是感谢各位!结贴了
yuhan1573 2009-04-30
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 llsen 的回复:]
引用 8 楼 yuhan1573 的回复:
引用 1 楼 zgke 的回复:
ID是自动增长字段把.


很感谢关注,但是这样连问题都没看清,就抛出来个有技巧性的推测,小弟是在不敢恭维。。


大佬你也敢怀疑
真佩服你的勇气

你的问题就是由于这个原因导致的
大佬问题看清了
[/Quote]

我没有说他说的不对~
首先,我问题中已经提到了ID是自动增长列。
其次,我当然知道问题是因为ID自动增长所致!就是贴出来想求教下有没有办法解决这个问题。
再次,我是菜鸟,但是我也不希望看到自己辛苦敲了半天的问题,别人却跟上一句没任何信息量的回复。
最后,我对任何大牛都是崇拜的,但是也有自己的想法。谢谢
marvelstack 2009-04-30
  • 打赏
  • 举报
回复
回楼主,你的设计本身就是有矛盾的呀,可能过一段时间您会意识到这一点。
yuhan1573 2009-04-29
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 zzxap 的回复:]
用sqlbulkcopy
[/Quote]

我用的是mysql数据库,这东西能用吗?

郁闷啊~这问题真解决不了了吗?抽象出来就是如何向DataTable中添加数据,指定的自动增长属性ID不被忽略。
yuhan1573 2009-04-29
  • 打赏
  • 举报
回复
首先感谢秋枫(zhzuo)对这一问题的热心详细解答。

对于你的回答有几点不明白的地方,请教如下,望指点:

1.对于数据库来说,设置了自增长列ID的情况下,向其中指定ID插入数据,应该不会忽略所指定的ID。
比如当前有3项数据ID为1-3,然后我指定ID为5插入,那么结果应该是有4项数据ID为1,2,3,5.而不会是1,2,3,4 吧?当然如果我不指定ID插入,结果会是1,2,3,4;

2.对于上一条的解释应该是yangqidong回复中提到的,用DataAdapter提交数据会忽略ID。

3.你提供的解决方案中,第一条当然不会采用,数据库不能随便改。
至于第二条是不是先插入数据提交到数据库中,再即时更新数据库更改的内容到本地的DataTable??
不知道理解的对不对?可是如果这样的话,也不是我想要的。
我仅仅是想能插入指定的ID进数据库,而不是在数据提交的过程中给忽略。。。

不管怎样,还是感谢各位的帮忙。。。

marvelstack 2009-04-29
  • 打赏
  • 举报
回复
你在DataTable里面指定ID列的值没有问题,但是你在l数据库里面对应的ID列中设置了自增长,想让两者的值一样,那是你的不对了,本来这样的做法就是矛盾的,如果数据库的自增长字段可以被你通过代码轻易修改,那还叫自增长吗,从另一方面讲数据库自增长功能为并发插入记录提供了方便,并不适合于让你自己代码修改。
解决办法.
1.调整数据库,修改为非自增长列。
2.如果还是自增长列,那可以在新数据插入到表后,获取新生成的ID数据通过输出参数或返回值反填到对应的DataTable中,维持两者的一致。

一般都采用第二种做法。给楼主一些参考。
对于包含自增长的多条数据更新到数据库反填回DataTable这个问题可以这样来解决,
DataColumn dc = dt.Columns["id"];//这一列对应的数据库中的表字段是自增列,

在内存DataTable中进行批输入更新时不能马上得到新输入的上一条记录的主键,
所以建立临时唯一主键如下:
dc.AutoIncrement = true;//设置该列为自增长,
dc.AutoIncrementSeed = -1;//新增列的初始值。
dc.AutoIncrementStep = -1;//列的值自动递增的数值。默认为 1。

这样你添加第一条新增数据的时候临时主键为-1,
第二条为-2,
...
在使用DataAdapter.Update(dt);进行更新的时候,
如果数据源是Sql Server那使用存储过程输出参数把自增主键输出会自动更新新增的DataRow,
比如上面的-1,-2,-3等自动会更新成实际数据库中的自增主键值。
这种方式具体可以看我的一片文章,
http://blog.csdn.net/zhzuo/archive/2004/08/06/67037.aspx
如果是Access或其他数据库就有点麻烦,回填实现如下:
注册DataAdapter.RowUpdated事件。
da.RowUpdated += new OleDbRowUpdatedEventHandler(da_RowUpdated);

事件处理程序,
private static void da_RowUpdated(object sender, OleDbRowUpdatedEventArgs e)
{
if(e.Status == UpdateStatus.Continue && e.StatementType = StatementType.Insert)
{
OleDbConnection conn = new OleDbConnection("连接字符串");
OleDbCommand comm = new OleDbCommand("SELECT @@IDENTITY",conn);
conn.Open();
e.Row["id"] = (int)comm.ExecuteScalar();//得到最新递增值更新到内存DataTable中刚更新的DataRow.
e.Row.AcceptChanges();
conn.Close();
}
}

//处理程序中的每次生成conn,和comm没有必要,你可以只初始化一次,这里这么写只是为了说明过程,而且也没有必要多次打开或关闭连接。



zzxap 2009-04-28
  • 打赏
  • 举报
回复
用sqlbulkcopy
yuhan1573 2009-04-28
  • 打赏
  • 举报
回复
现在的目的是这样:

想从一个数据库中的一张表中将所有表的内容填充到本地的一个DataTable缓存中去,
然后将这个缓存(即源表内容)通过DataApdater方式转储到另一个数据库中拥有同样结构的目的表中。
有没有什么好的建议??
yuhan1573 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 yangqidong 的回复:]
引用 14 楼 yangqidong 的回复:

汗。。。原来是mysql,还以为是mssql
[/Quote]

那现在是无法可解了??查看了下似乎有个设置 DataSet.DataTable.Column.Autoincrement=false.有谁熟悉这个设置?
yangqidong 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 yuhan1573 的回复:]
引用 14 楼 yangqidong 的回复:


IDENTITY_INSERT 意思就是,是自动增长的,但却又是可以插入的


命令是:set identity_insert 表名 on???
这命令MYSQL中能用吗?怎么提示不存在的命令?
[/Quote]
汗。。。原来是mysql,还以为是mssql
yuhan1573 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 yangqidong 的回复:]

IDENTITY_INSERT 意思就是,是自动增长的,但却又是可以插入的
[/Quote]

命令是:set identity_insert 表名 on???
这命令MYSQL中能用吗?怎么提示不存在的命令?
蓝海D鱼 2009-04-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zgke 的回复:]
ID是自动增长字段把.
[/Quote]up
zzxap 2009-04-28
  • 打赏
  • 举报
回复
[code=C#]
protected void btnBulkCopy_Click(object sender, EventArgs e)
{
String ShajarConString =ConfigurationManager.ConnectionStrings["DSN_Shajar"].ConnectionString;
String NorthWindConString = ConfigurationManager.ConnectionStrings["DSN_Northwind"].ConnectionString;
SqlConnection ShajarCon = new SqlConnection(ShajarConString);
SqlConnection NorthwindCon = new SqlConnection(NorthWindConString);
string sql1 = " SELECT ID, First_Name, Last_Name, " +
" 'Shajar' as Source FROM MailingList_Temp ";
SqlCommand ShajarCom = new SqlCommand(sql1,ShajarCon);
SqlDataReader ShajarReader;
ShajarCon.Open();

SqlBulkCopy NorthWindBulkOp= new SqlBulkCopy(NorthWindConString, SqlBulkCopyOptions.UseInternalTransaction);

NorthWindBulkOp.DestinationTableName = "Employees";

NorthWindBulkOp.ColumnMappings.Add("Id", "EmployeeID");
NorthWindBulkOp.ColumnMappings.Add("First_Name", "FirstName");
NorthWindBulkOp.ColumnMappings.Add("Last_Name", "LastName");

SqlBulkCopyColumnMapping JobTitleColMap= new SqlBulkCopyColumnMapping("Source1", "Title");
NorthWindBulkOp.ColumnMappings.Add(JobTitleColMap);
NorthWindBulkOp.BulkCopyTimeout = 500000000;

NorthWindBulkOp.SqlRowsCopied +=
new SqlRowsCopiedEventHandler(OnRowsCopied);

NorthWindBulkOp.NotifyAfter = 1000;

ShajarReader = ShajarCom.ExecuteReader();

try
{
NorthWindBulkOp.WriteToServer(ShajarReader);
}
catch (Exception ex)
{
lblResult.Text = ex.Message;
}
finally
{
ShajarReader.Close();
}
}

private void OnRowsCopied(object sender, SqlRowsCopiedEventArgs args)
{
lblCounter.Text += args.RowsCopied.ToString() + " rows are copied<Br>";
}
[/CODE]
加载更多回复(13)

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧