.NET Core2.1迁移到3.1后dbContext.Database.GetDbConnection报错如何解决
.NET Core 3.1 数据库连接迁移适配方案
问题根源
- .NET Core 3.0 及以上版本的 EF Core SqlServer 提供程序默认将底层驱动从
System.Data.SqlClient切换为Microsoft.Data.SqlClient,两类命名空间下的SqlConnection、SqlParameter等类型不兼容 - 报错"无法将'Microsoft.Data.SqlClient.SqlConnection'转换为'string'",说明当前使用的
SqlHelper.FillDatatable方法第一个入参要求的是连接字符串而非连接对象,或者该SqlHelper是基于旧的System.Data.SqlClient封装,不识别新的驱动类型
具体修改步骤
1. 安装依赖NuGet包
优先确认项目已安装和.NET Core 3.1版本匹配的稳定版包:
Microsoft.EntityFrameworkCore.SqlServer3.1.x版本Microsoft.Data.SqlClient
2. 替换命名空间
删除旧的System.Data.SqlClient引用,启用新的驱动引用:
using System; using System.Collections.Generic; using System.Data; using System.Data.Common; // 删掉旧驱动引用 // using System.Data.SqlClient; // 启用新驱动引用 using Microsoft.Data.SqlClient; using System.Linq;
3. 适配调用代码
分两种场景处理:
场景1:可以修改SqlHelper源码(推荐)
将FillDatatable方法的第一个入参类型改为DbConnection/Microsoft.Data.SqlClient.SqlConnection,同时将方法内部用到的所有SqlConnection、SqlParameter都替换为Microsoft.Data.SqlClient命名空间下的类型,修改后调用代码不需要额外调整,保持原有写法即可:
public UserRepository(dbContext db) : base(db) { _db= db; } // 强转要对应新命名空间下的SqlConnection var conn = (SqlConnection)_db.Database.GetDbConnection(); DataTable dtMissingDates = new DataTable(); SqlParameter parUserId = new SqlParameter("@UserId", userId); SqlParameter parDepots = new SqlParameter("@DepotNo", depono); SqlParameter parDepartment = new SqlParameter("@DepartmentID", department); SqlParameter parDate = new SqlParameter("@DateTo",attdate); SqlHelper.FillDatatable(conn , CommandType.StoredProcedure , StoredProcedureConstants.GET_DEPOT_MISSING_ATT_POPUP , dtMissingDates , MTSGOConstants.DEFAULT_COMMAND_TIME_OUT , parUserId , parDepots , parDepartment ,parDate);
场景2:无法修改SqlHelper源码
如果SqlHelper第一个参数确实要求传入连接字符串,直接从EF Core配置中读取连接字符串传入即可,注意参数类型要和SqlHelper依赖的驱动命名空间匹配:
// 不需要获取连接对象,直接读连接字符串 var connStr = _db.Database.GetConnectionString(); DataTable dtMissingDates = new DataTable(); // 如果SqlHelper是基于旧System.Data.SqlClient封装,参数要使用旧命名空间的类型 System.Data.SqlClient.SqlParameter parUserId = new System.Data.SqlClient.SqlParameter("@UserId", userId); System.Data.SqlClient.SqlParameter parDepots = new System.Data.SqlClient.SqlParameter("@DepotNo", depono); System.Data.SqlClient.SqlParameter parDepartment = new System.Data.SqlClient.SqlParameter("@DepartmentID", department); System.Data.SqlClient.SqlParameter parDate = new System.Data.SqlClient.SqlParameter("@DateTo",attdate); SqlHelper.FillDatatable(connStr , CommandType.StoredProcedure , StoredProcedureConstants.GET_DEPOT_MISSING_ATT_POPUP , dtMissingDates , MTSGOConstants.DEFAULT_COMMAND_TIME_OUT , parUserId , parDepots , parDepartment ,parDate);
注意事项
- 从
_db.Database.GetDbConnection()获取的连接对象由EF Core管理生命周期,不要手动调用Dispose释放,避免影响EF Core的常规数据库操作 - 同一项目中尽量不要混用两个命名空间下的Sql相关类型,避免出现类型不匹配的转换错误
内容的提问来源于stack exchange,提问作者Alan Pauil
相关产品推荐
相关产品推荐

