You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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.SqlClient
  • EntityFramework(选择最新兼容.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 13:08:09