.NET 4.8 MVC项目中AspNet.Identity.EntityFramework适配Microsoft.Data.SqlClient问题
解决ASP.NET Identity EntityFramework中替换System.Data.SqlClient为Microsoft.Data.SqlClient的类型转换错误
问题根源
Microsoft.AspNet.Identity.EntityFramework依赖的Entity Framework 6(EF6)默认绑定System.Data.SqlClient,直接传入Microsoft.Data.SqlClient.SqlConnection会触发EF内部的类型转换失败,同时EF迁移历史仓库也会默认使用旧的SqlClient组件,导致兼容性问题。
解决步骤
1. 安装必要NuGet包
确保项目安装以下兼容.NET 4.8的包:
Microsoft.Data.SqlClientEntityFramework(选择最新兼容.NET 4.8的EF6版本)Microsoft.AspNet.Identity.EntityFramework(与项目现有版本匹配)
2. 配置EF使用Microsoft.Data.SqlClient
创建自定义DbConfiguration,替换EF默认的SqlClient组件:
using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Data.Common; using Microsoft.Data.SqlClient; using System.Data.Entity.Migrations.History; // 自定义连接工厂,使用Microsoft.Data.SqlClient public class MicrosoftSqlConnectionFactory : IDbConnectionFactory { public DbConnection CreateConnection(string nameOrConnectionString) { return new SqlConnection(nameOrConnectionString); } } // 自定义迁移历史上下文,适配Microsoft.Data.SqlClient public class MicrosoftSqlHistoryContext : HistoryContext { public MicrosoftSqlHistoryContext(DbConnection connection, string defaultSchema) : base(connection, defaultSchema) { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 保持默认迁移表结构,无需额外修改 } } // EF全局配置 public class SetMicrosoftDataSqlClient : DbConfiguration { public SetMicrosoftDataSqlClient() { // 注册Microsoft.Data.SqlClient的工厂和服务 SetProviderFactory("System.Data.SqlClient", SqlClientFactory.Instance); SetProviderServices("System.Data.SqlClient", System.Data.Entity.SqlServer.SqlProviderServices.Instance); // 设置默认连接工厂 SetDefaultConnectionFactory(new MicrosoftSqlConnectionFactory()); // 替换迁移历史上下文 SetHistoryContext("System.Data.SqlClient", (connection, defaultSchema) => new MicrosoftSqlHistoryContext(connection, defaultSchema)); } }
3. 修正IdentityDbContext实现
移除手动传入SqlConnection的逻辑,让EF通过配置自动创建连接,避免类型不匹配:
[DbConfigurationType(typeof(SetMicrosoftDataSqlClient))] public class ApplicationIdentityDbContext : IdentityDbContext<ApplicationUser> { public ApplicationIdentityDbContext(string connectionString) : base(connectionString) { // 移除手动设置DbConfiguration的代码,已通过Attribute指定全局配置 } public static ApplicationIdentityDbContext Create() { var connectionString = ConfigurationManager.ConnectionStrings["IdentityDb"].ConnectionString; return new ApplicationIdentityDbContext(connectionString); } }
4. 调整连接字符串
配置支持Azure托管标识的连接字符串,注意providerName保持System.Data.SqlClient(EF会通过配置映射到Microsoft.Data.SqlClient):
<connectionStrings> <add name="IdentityDb" connectionString="Server=tcp:你的SQL服务器名.database.windows.net,1433;Database=你的数据库名;Authentication=Active Directory Default;" providerName="System.Data.SqlClient" /> </connectionStrings>
5. 确保配置全局生效
如果[DbConfigurationType]Attribute未生效,可在Global.asax.cs的Application_Start方法中手动加载配置:
protected void Application_Start() { // 其他初始化代码... DbConfiguration.SetConfiguration(new SetMicrosoftDataSqlClient()); }
关键注意事项
- 禁止手动向
IdentityDbContext构造函数传入Microsoft.Data.SqlClient.SqlConnection,基类内部依赖System.Data.SqlClient的类型定义,会触发强制转换异常。 - 确保所有EF相关操作都通过配置的连接工厂创建连接,避免混合使用两种SqlClient组件。
内容的提问来源于stack exchange,提问作者John Lee
相关产品推荐
相关产品推荐

