如何将Web API数据导入SQL Server数据库及测试API有效性
如何将Web API数据导入SQL Server数据库并测试API
先修正现有API的问题(确保API能正常运行)
你的代码存在几个语法和资源管理问题,先修正这些才能保证API正常工作:
1. SQL JOIN语法错误
INNER JOIN必须用ON指定关联条件,而非WHERE,两个查询都需要修正:
- 修正后
GetAll的SQL语句:SELECT U.UserID, U.Name, U.Mobile, U.Age, U.Birthday, A.Address, A.Country From tbluser U INNER JOIN tblAddress A ON A.Country = U.Country - 修正后
GetCountry的SQL语句:SELECT U.UserID, U.Name, U.Mobile, U.Age, U.Birthday, A.Address, A.Country From tbluser U INNER JOIN tblAddress A ON A.Country = U.Country WHERE CHARINDEX(@country, A.Country) = 1 ORDER BY U.UserId
2. 对象初始化语法错误
Birthday行末尾缺少逗号,会导致编译失败,同时GetValue(01)应改为GetValue(1)避免歧义:
web.Add(new webapi() { UserId = Convert.ToString(sdr.GetValue(0)), Name = Convert.ToString(sdr.GetValue(1)), Mobile = Convert.ToString(sdr.GetValue(2)), Age = (sdr.GetValue(3) != DBNull.Value) ? Convert.ToInt32(sdr.GetValue(3)) : 0, Birthday = (sdr.GetValue(4) != DBNull.Value) ? Convert.ToDateTime(sdr.GetValue(4)) : (DateTime?)null, Address = Convert.ToString(sdr.GetValue(5)), Country = Convert.ToString(sdr.GetValue(6)) });
3. DataReader资源泄漏
GetAll方法中的SqlDataReader未用using包裹,会导致数据库连接资源无法及时释放,修正为:
using (SqlDataReader sdr = cmd.ExecuteReader()) { while (sdr.Read()) { // 对象初始化代码 } }
4. 数据库连接管理
确保connection对象在方法内创建并使用using包裹,避免连接池耗尽:
using (SqlConnection connection = new SqlConnection("你的数据库连接字符串")) { connection.Open(); // 执行SqlCommand的逻辑 }
测试API是否正常工作
修正代码后,可通过以下方式验证:
- 使用Postman或Swagger发送GET请求:
- 测试
GetAll:访问http://localhost:端口号/控制器名/GetAll,查看返回的JSON数据是否与数据库查询结果一致。 - 测试
GetCountry:访问http://localhost:端口号/控制器名/GetCountry?country=目标国家,验证返回结果是否符合筛选条件。
- 测试
将Web API数据导入SQL Server的方法
你提到的DataReader实现导入,通常分为两种场景:
场景1:将当前API返回的数据导入到目标SQL Server库
编写客户端程序(如控制台应用)调用API获取数据,再批量插入到目标数据库:
// 调用API获取数据 HttpClient client = new HttpClient(); var response = await client.GetFromJsonAsync<List<webapi>>("http://localhost:端口号/控制器名/GetAll"); // 批量插入到目标数据库 using (SqlConnection conn = new SqlConnection("目标库连接字符串")) { conn.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn)) { bulkCopy.DestinationTableName = "目标表名"; // 映射实体属性与数据库列名(属性与列名一致可省略) bulkCopy.ColumnMappings.Add("UserId", "UserID"); bulkCopy.ColumnMappings.Add("Name", "Name"); bulkCopy.ColumnMappings.Add("Mobile", "Mobile"); bulkCopy.ColumnMappings.Add("Age", "Age"); bulkCopy.ColumnMappings.Add("Birthday", "Birthday"); bulkCopy.ColumnMappings.Add("Address", "Address"); bulkCopy.ColumnMappings.Add("Country", "Country"); // 将数据转换为DataTable DataTable dt = new DataTable(); dt.Columns.Add("UserId", typeof(string)); dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Mobile", typeof(string)); dt.Columns.Add("Age", typeof(int)); dt.Columns.Add("Birthday", typeof(DateTime)); dt.Columns.Add("Address", typeof(string)); dt.Columns.Add("Country", typeof(string)); foreach (var item in response) { DataRow row = dt.NewRow(); row["UserId"] = item.UserId; row["Name"] = item.Name; row["Mobile"] = item.Mobile; row["Age"] = item.Age; row["Birthday"] = item.Birthday ?? DBNull.Value; row["Address"] = item.Address; row["Country"] = item.Country; dt.Rows.Add(row); } bulkCopy.WriteToServer(dt); } }
场景2:在Web API中实现数据导入(从外部数据源读取后写入SQL Server)
新增POST方法接收外部数据并写入数据库,使用参数化查询避免SQL注入:
[HttpPost] public IHttpActionResult ImportData(List<webapi> data) { if (data == null || data.Count == 0) { return BadRequest("没有可导入的数据"); } using (SqlConnection conn = new SqlConnection("你的数据库连接字符串")) { conn.Open(); string sql = @"INSERT INTO tbluser (UserID, Name, Mobile, Age, Birthday, Country) VALUES (@UserId, @Name, @Mobile, @Age, @Birthday, @Country); INSERT INTO tblAddress (Address, Country) VALUES (@Address, @Country);"; using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.Add("@UserId", SqlDbType.VarChar); cmd.Parameters.Add("@Name", SqlDbType.VarChar); cmd.Parameters.Add("@Mobile", SqlDbType.VarChar); cmd.Parameters.Add("@Age", SqlDbType.Int); cmd.Parameters.Add("@Birthday", SqlDbType.DateTime); cmd.Parameters.Add("@Address", SqlDbType.VarChar); cmd.Parameters.Add("@Country", SqlDbType.VarChar); foreach (var item in data) { cmd.Parameters["@UserId"].Value = item.UserId; cmd.Parameters["@Name"].Value = item.Name; cmd.Parameters["@Mobile"].Value = item.Mobile; cmd.Parameters["@Age"].Value = item.Age; cmd.Parameters["@Birthday"].Value = item.Birthday ?? DBNull.Value; cmd.Parameters["@Address"].Value = item.Address; cmd.Parameters["@Country"].Value = item.Country; cmd.ExecuteNonQuery(); } } } return Ok($"成功导入{data.Count}条数据"); }
注意事项
- 始终使用参数化查询防止SQL注入。
- 批量导入优先使用
SqlBulkCopy提升性能,尤其是数据量较大时。 - 数据库连接字符串应存储在配置文件(如
appsettings.json)中,禁止硬编码。
内容的提问来源于stack exchange,提问作者user19928919
相关产品推荐
相关产品推荐

