如何在C#中将CSV导入SQL Server Express并转换数据类型
问题分析与修正方案
你的代码存在几个关键问题,会导致导入失败或数据类型转换错误,以下是具体问题和修复后的实现:
核心问题梳理
- CsvReader初始化冗余:无需将
StreamReader强制转换为IParser,CsvReader构造函数直接支持TextReader类型参数。 - 日期转换不规范:
SqlDateTime.Parse是旧版SQL专属方法,针对ISO 8601格式(YYYY-MM-DDTHH:mm:ssZ)的日期,推荐使用标准DateTime.ParseExact确保转换准确性,同时需处理空值场景。 - SqlBulkCopy数据源错误:
- 读取完成后
csv1已被using块释放,此时调用WriteToServer会抛出资源已释放异常; StreamReader不能直接转换为IDataReader,第二个CSV文件同样需要通过CsvReader读取并转换为合法数据源。
- 读取完成后
- 文件资源冲突:同时打开两个
StreamReader可能触发文件锁定,建议分开处理不同CSV文件。
修正后的代码实现
1. 定义实体类(确保类型匹配)
public class TicketCSV { public int TicketID { get; set; } public string TicketTitle { get; set; } public string TicketStatus { get; set; } public string CustomerName { get; set; } public string TechnicianFullName { get; set; } public string TicketResolvedDate { get; set; } // 先以字符串读取,后续转换为DateTime } // 第二个CSV对应的实体类(根据WerkUren表头定义) public class WorkHourCSV { // 按实际CSV表头定义属性 // 示例:public int HourID { get; set; } // public string TicketID { get; set; } // ... }
2. 读取CSV并批量导入SQL Server
// 处理第一个CSV:GeslotenTickets List<TicketCSV> tickets = new List<TicketCSV>(); using (var reader1 = new StreamReader(OutputClosedTickets)) using (var csv1 = new CsvReader(reader1, CultureInfo.InvariantCulture)) { csv1.Configuration.Delimiter = ","; csv1.Configuration.MissingFieldFound = null; csv1.Configuration.PrepareHeaderForMatch = (header, index) => header.ToLower(); // 强类型读取CSV数据 tickets = csv1.GetRecords<TicketCSV>().ToList(); } // 转换为DataTable适配SqlBulkCopy DataTable ticketTable = new DataTable(); ticketTable.Columns.Add("TicketID", typeof(int)); ticketTable.Columns.Add("TicketTitle", typeof(string)); ticketTable.Columns.Add("TicketStatus", typeof(string)); ticketTable.Columns.Add("CustomerName", typeof(string)); ticketTable.Columns.Add("TechnicianFullName", typeof(string)); ticketTable.Columns.Add("TicketResolvedDate", typeof(DateTime)); foreach (var ticket in tickets) { var row = ticketTable.NewRow(); row["TicketID"] = ticket.TicketID; row["TicketTitle"] = ticket.TicketTitle; row["TicketStatus"] = ticket.TicketStatus; row["CustomerName"] = ticket.CustomerName; row["TechnicianFullName"] = ticket.TechnicianFullName; // 处理日期转换,兼容空值场景 row["TicketResolvedDate"] = string.IsNullOrEmpty(ticket.TicketResolvedDate) ? DBNull.Value : DateTime.ParseExact(ticket.TicketResolvedDate, "yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture); ticketTable.Rows.Add(row); } // 批量导入GeslotenTickets表 using (var bulkCopy = new SqlBulkCopy(connectionString)) { bulkCopy.DestinationTableName = "GeslotenTickets"; // 显式列映射(确保CSV列与数据库列一一对应) bulkCopy.ColumnMappings.Add("TicketID", "TicketID"); bulkCopy.ColumnMappings.Add("TicketTitle", "TicketTitle"); bulkCopy.ColumnMappings.Add("TicketStatus", "TicketStatus"); bulkCopy.ColumnMappings.Add("CustomerName", "CustomerName"); bulkCopy.ColumnMappings.Add("TechnicianFullName", "TechnicianFullName"); bulkCopy.ColumnMappings.Add("TicketResolvedDate", "TicketResolvedDate"); bulkCopy.WriteToServer(ticketTable); } // 处理第二个CSV:WerkUren using (var reader2 = new StreamReader(OutputWorkhours)) using (var csv2 = new CsvReader(reader2, CultureInfo.InvariantCulture)) { csv2.Configuration.Delimiter = ","; csv2.Configuration.MissingFieldFound = null; csv2.Configuration.PrepareHeaderForMatch = (header, index) => header.ToLower(); var workHours = csv2.GetRecords<WorkHourCSV>().ToList(); DataTable workHourTable = new DataTable(); // 按WerkUren数据库表结构添加列 // 示例:workHourTable.Columns.Add("HourID", typeof(int)); // workHourTable.Columns.Add("TicketID", typeof(string)); // ... foreach (var hour in workHours) { var row = workHourTable.NewRow(); // 填充行数据 // 示例:row["HourID"] = hour.HourID; // row["TicketID"] = hour.TicketID; // ... workHourTable.Rows.Add(row); } using (var bulkCopy = new SqlBulkCopy(connectionString)) { bulkCopy.DestinationTableName = "WerkUren"; // 添加对应列映射 // ... bulkCopy.WriteToServer(workHourTable); } }
额外注意事项
- 确保数据库表
GeslotenTickets的列类型匹配:TicketID为int,TicketResolvedDate建议使用datetime2(比datetime支持更广的日期范围)。 - 如果CSV中存在特殊字符或换行,可在
CsvReader.Configuration中配置TrimOptions处理多余空格。
内容的提问来源于stack exchange,提问作者NightBladium
相关产品推荐
相关产品推荐

