C#实现POS系统中根据托盘数量将单行拆分为多行插入
C#实现POS系统单列数据拆分多行插入方案
需求说明
将源表中单条记录,根据Qty of Pallets(托盘数量)字段拆分为对应行数的记录,插入到目标表中,每条拆分后的记录使用Quantity Of A Pallet/Per Box作为Qty in Box的值。
源表结构与示例数据
| ID | Item Code | Total Qty | Qty of Pallets | Quantity Of A Pallet/Per Box | Date |
|---|---|---|---|---|---|
| 00001 | Item 1 | 384 | 4 | 96 | 12/07/2014 |
目标表结构与预期结果
| ID | Item Code | Qty in Box | Date |
|---|---|---|---|
| 00001 | Item 1 | 96 | 12/07/2014 |
| 00001 | Item 1 | 96 | 12/07/2014 |
| 00001 | Item 1 | 96 | 12/07/2014 |
| 00001 | Item 1 | 96 | 12/07/2014 |
实现步骤
1. 定义实体类
先对应源表和目标表创建实体类,方便数据操作:
// 源表实体 public class SourceInventory { public string ID { get; set; } public string ItemCode { get; set; } public int TotalQty { get; set; } public int QtyOfPallets { get; set; } public int QuantityPerPallet { get; set; } public DateTime Date { get; set; } } // 目标表实体 public class TargetInventory { public string ID { get; set; } public string ItemCode { get; set; } public int QtyInBox { get; set; } public DateTime Date { get; set; } }
2. 拆分记录逻辑
编写方法将单条源记录拆分为多条目标记录:
public static List<TargetInventory> SplitInventory(SourceInventory source) { var targetList = new List<TargetInventory>(); // 根据托盘数量生成对应条数的记录 for (int i = 0; i < source.QtyOfPallets; i++) { targetList.Add(new TargetInventory { ID = source.ID, ItemCode = source.ItemCode, QtyInBox = source.QuantityPerPallet, Date = source.Date }); } return targetList; }
3. 批量插入到数据库
以下提供两种常见的数据库插入方式:
方式一:使用Entity Framework Core批量插入
如果项目使用EF Core,可直接将拆分后的列表批量添加:
using (var context = new YourDbContext()) { // 假设已经获取到源记录 var sourceRecord = context.SourceInventories.FirstOrDefault(s => s.ID == "00001"); if (sourceRecord != null) { var targetRecords = SplitInventory(sourceRecord); context.TargetInventories.AddRange(targetRecords); context.SaveChanges(); } }
方式二:使用ADO.NET批量插入
若使用原生ADO.NET,可通过SqlBulkCopy提升插入效率:
public static void BulkInsertToTarget(List<TargetInventory> targetList) { // 数据库连接字符串,根据实际配置修改 string connectionString = "Your_Connection_String"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection)) { bulkCopy.DestinationTableName = "TargetInventory"; // 目标表名 // 映射列名(如果实体属性和数据库列名一致,可省略,否则需手动映射) bulkCopy.ColumnMappings.Add("ID", "ID"); bulkCopy.ColumnMappings.Add("ItemCode", "Item Code"); bulkCopy.ColumnMappings.Add("QtyInBox", "Qty in Box"); bulkCopy.ColumnMappings.Add("Date", "Date"); // 将列表转为DataTable(SqlBulkCopy需要DataTable或IDataReader) DataTable dt = new DataTable(); dt.Columns.Add("ID", typeof(string)); dt.Columns.Add("Item Code", typeof(string)); dt.Columns.Add("Qty in Box", typeof(int)); dt.Columns.Add("Date", typeof(DateTime)); foreach (var item in targetList) { dt.Rows.Add(item.ID, item.ItemCode, item.QtyInBox, item.Date); } bulkCopy.WriteToServer(dt); } } } // 使用示例 // var source = GetSourceRecord(); // 从数据库获取源记录 // var targets = SplitInventory(source); // BulkInsertToTarget(targets);
注意事项
- 数据验证:需确保源记录的
Qty of Pallets为正整数,避免生成空列表;可添加校验逻辑验证TotalQty是否等于Qty of Pallets * Quantity Of A Pallet/Per Box,防止数据不一致。 - 性能优化:批量插入时优先使用
SqlBulkCopy或EF Core批量扩展包,避免循环单条插入导致性能损耗。
内容的提问来源于stack exchange,提问作者ledio4
相关产品推荐
相关产品推荐

