无法在另一个 foreach mysql C# 中的 foreach 循环中获取 Last_inserted_id
Posted
技术标签:
【中文标题】无法在另一个 foreach mysql C# 中的 foreach 循环中获取 Last_inserted_id【英文标题】:Cannot Fetch the Last_inserted_id in a foreach loop inside another foreach mysql C# 【发布时间】:2021-08-06 10:49:44 【问题描述】:上图显示了 mysql Tables 中的输出。 我的问题是它无法获取 ORDERTABLE 中 last_inserted_id 值的值,因为它是 ItemTable itemid 中的参考值。
这是我在 SAVEORDER 和 SAVEITEM 中的代码
描述 = 是我将数据拆分为 foreach 并将其保存在项目表中的位置。 每个拆分都应使用相应的 orderid 保存每个数据,我尝试了 last_inserted_id 而不是 MaxID,因为我希望它由 1-3 个用户同时完成,而不会出现数据完整性问题。
private void SaveOrder()
try
foreach (DataGridViewRow row in DGSingleOrders.Rows)
using (MySqlCommand cmd = new MySqlCommand())
cmd.CommandText = "INSERT INTO single_order (customerid, category, type, description, code, color, price, status, transaction, attendee) VALUES (@customerid, @category, @type, @description, @code, @color, @price, @status, @transaction, @attendee)";
cmd.CommandType = CommandType.Text;
cmd.Connection = db.con;
db.con.Open();
cmd.Parameters.Add("@customerid", MySqlDbType.VarChar).Value = OrderID;
cmd.Parameters.Add("@category", MySqlDbType.VarChar).Value = row.Cells[0].Value.ToString();
cmd.Parameters.Add("@type", MySqlDbType.VarChar).Value = row.Cells[1].Value.ToString();
cmd.Parameters.Add("@description", MySqlDbType.VarChar).Value = row.Cells[2].Value.ToString();
cmd.Parameters.Add("@code", MySqlDbType.VarChar).Value = row.Cells[3].Value.ToString();
cmd.Parameters.Add("@color", MySqlDbType.VarChar).Value = row.Cells[4].Value.ToString();
cmd.Parameters.Add("@price", MySqlDbType.VarChar).Value = row.Cells[5].Value.ToString();
cmd.Parameters.Add("@status", MySqlDbType.VarChar).Value = SaveAs;
cmd.Parameters.Add("@transaction", MySqlDbType.VarChar).Value = DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss tt");
cmd.Parameters.Add("@attendee", MySqlDbType.VarChar).Value = attendee;
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
db.con.Close();
//Check this first
using (MySqlCommand cmd = new MySqlCommand())
cmd.CommandText = "SELECT LAST_INSERT_ID()";
cmd.Connection = db.con;
db.con.Open();
using (MySqlDataReader reader = cmd.ExecuteReader())
long id;
while (reader.Read())
id = reader.GetInt64(0);
ItemID = id.ToString();
db.con.Close();
catch (Exception e)
MessageBox.Show(e.Message,"ORDER");
db.con.Close();
return;
private void SaveItem()
//Getting Each Data
foreach (DataGridViewRow row in DGSingleOrders.Rows)
string item = row.Cells[1].Value.ToString();
string type = row.Cells[0].Value.ToString();
string str = row.Cells[2].Value.ToString();
string code = row.Cells[3].Value.ToString();
string color = row.Cells[4].Value.ToString();
List<string> descr = str.Split('+').ToList<string>();
//Splitting Description
//Adding Split to a DataTable
foreach (var l in descr)
OrderRow = l;
try
using (MySqlCommand cmd = new MySqlCommand())
cmd.CommandText = "INSERT INTO single_item (orderid, type, item, brand, code, color, eventdate, orderstatus, itemstatus, orderchecker, attendee)VALUES(@orderid, @type, @item, @brand, @code, @color, @eventdate, @orderstatus, @itemstatus, @orderchecker, @attendee)";
cmd.CommandType = CommandType.Text;
cmd.Connection = db.con;
cmd.Parameters.Add("@orderid", MySqlDbType.VarChar).Value = ItemID;
cmd.Parameters.Add("@type", MySqlDbType.VarChar).Value = type;
cmd.Parameters.Add("@item", MySqlDbType.VarChar).Value = OrderRow;
cmd.Parameters.Add("@brand", MySqlDbType.VarChar).Value = "-";
cmd.Parameters.Add("@code", MySqlDbType.VarChar).Value = code;
cmd.Parameters.Add("@color", MySqlDbType.VarChar).Value = color;
cmd.Parameters.Add("@eventdate", MySqlDbType.VarChar).Value = eventDay;
cmd.Parameters.Add("@orderstatus", MySqlDbType.VarChar).Value = SaveAs;
cmd.Parameters.Add("@itemstatus", MySqlDbType.VarChar).Value = "Good";
cmd.Parameters.Add("@orderchecker", MySqlDbType.VarChar).Value = "Not Updated";
cmd.Parameters.Add("@attendee", MySqlDbType.VarChar).Value = atendee;
db.con.Open();
cmd.ExecuteNonQuery();
db.con.Close();
dtItems.Clear();
catch (Exception e)
MessageBox.Show(e.Message);
db.con.Close();
return;
SaveItem();
我添加了 SaveItem(); SaveOrder() 中的方法; ForeachLoop 这样就可以和 ORDER 表一起保存,并且可以获取 Last_inserted_id 的数据但还是得到第一个 ID,我也试过把它放到 foreach 循环中,但是之后就不能得到 Order ID 的结果,并以不同的方式保存数据。
【问题讨论】:
无论您对当前问题的解决方案如何,请注意cmd.Parameters.Add("@transaction", MySqlDbType.VarChar).Value = DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss tt");
看起来很有问题。为什么将日期时间存储在名为transaction
的列中?为什么将其存储为字符串而不是数据库中的日期时间?
我是这样存储的,因为我把它转换成多种格式,所以用户可以很容易地阅读它。如果我将它保存为本地 mysql 日期时间格式,将其格式化回来会给我带来奇怪的结果,但是你有什么想法,我怎样才能在循环中获取最后一个插入 id?我还是想不通。
我无法帮助您解决原来的问题。但是您存储日期的方式非常糟糕。格式化是显示问题,而不是存储问题。您占用了更多空间,使搜索变得缓慢,破坏了本地化的机会,并且通常使您的生活变得比需要的更难。
在调用cmd.ExecuteNonQuery()
进行"INSERT INTO single_order..."
查询之后阅读cmd.LastInsertedId
可能会让您的生活更轻松。这将使您避免"SELECT LAST_INSERT_ID()"
查询,并保证返回正确的值。
@BradleyGrainger 嘿,布拉德利,您可以将您的评论发布为答案,以便我将其标记为答案吗?
【参考方案1】:
您可以使用MySqlCommand.LastInsertedId
获取刚刚插入的行的ID,无需单独查询。它也保证包含正确的值,因为它直接来自 MySQL 对INSERT
语句的响应。
long itemId;
using (MySqlCommand cmd = new MySqlCommand())
cmd.CommandText = "INSERT INTO single_order (customerid, ...";
// ...
cmd.ExecuteNonQuery();
itemId = cmd.LastInsertedId;
// ...
using (MySqlCommand cmd = new MySqlCommand())
cmd.CommandText = "INSERT INTO single_item (orderid, ...";
cmd.Parameters.AddWithValue("@orderid", itemID);
// ...
【讨论】:
【参考方案2】:所以我想通了。
而不是使用 SELECT LAST_INSERT_ID() ,它有一些文档,它只返回已插入的第一个 ID。 Bradley Grainger 提议使用 MySqlCommand.InsertLastId;
我已经改成这个了。
cmd.ExecuteNonQuery();
cmd.Parameters.Add(new MySqlParameter("newId", cmd.LastInsertedId));
ItemID = Convert.ToInt32(cmd.Parameters["@newId"].Value);
MessageBox.Show(ItemID.ToString());
```
now it is working. It can fetch the lastInserted iD in each loop, and the beauty of it is it can be threadsafe and can work along with simultaneous insert.
Also this link help me. https://livshitz.wordpress.com/2011/10/28/returning-last-inserted-id-in-c-using-mysql-db-provider/
【讨论】:
以上是关于无法在另一个 foreach mysql C# 中的 foreach 循环中获取 Last_inserted_id的主要内容,如果未能解决你的问题,请参考以下文章
Oracle Dll 加载错误:无法在另一台机器上运行 C# 控制台应用程序