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

现有EF Database First的ASP.NET Web API项目添加Identity Framework报错如何解决

问题根因

核心错误由两个原因导致:

  1. Identity Framework 底层依赖 Code First 模式来生成、操作身份验证相关表(AspNetUsers、AspNetRoles 等),但你当前的atishEntities是 Database First 生成的上下文,OnModelCreating方法里直接抛出UnintentionalCodeFirstException阻断了 Identity 的模型配置逻辑,且 Database First 模式的 EDMX 上下文本身就不支持 Code First 的模型构建、迁移操作。
  2. 注册按钮的逻辑完全没有用到之前配置的 OWIN 托管的AppUserManager,直接实例化无参UserStore会默认读取DefaultConnection连接字符串,和现有配置完全脱节。
解决方案

推荐采用拆分上下文的方案,侵入性低、后续维护成本低:

方案1:拆分上下文(推荐)

不要混合业务的 Database First 上下文和 Identity 的 Code First 上下文,两个上下文操作同一个数据库即可:

步骤1:回滚原有上下文修改

把之前改的atishEntities继承关系恢复成原来继承DbContext的状态,不要修改自动生成的 Database First 上下文代码,避免后续更新 EDMX 时自定义代码被覆盖。

步骤2:新增 Identity 专用 Code First 上下文

新建独立的 Identity 上下文类:

using Microsoft.AspNet.Identity.EntityFramework;
using System.Data.Entity;

namespace EmployeeService
{
    public class AppIdentityDbContext : IdentityDbContext<IdentityUser>
    {
        public AppIdentityDbContext() : base("name=IdentityConnection")
        {
        }
        
        public static AppIdentityDbContext Create()
        {
            return new AppIdentityDbContext();
        }
    }
}

步骤3:新增 Identity 专用连接字符串

在 web.config 的<connectionStrings>节点添加纯 SQLClient 类型的连接字符串,指向同一个 atish 数据库:

<add name="IdentityConnection" connectionString="data source=.;initial catalog=atish;integrated security=True;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />

步骤4:调整 AppUserManager 和 Startup 配置

修改 AppUserManager 的 Create 方法,绑定新的 Identity 上下文:

public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
{
    var manager = new AppUserManager(
        new UserStore<IdentityUser>(context.Get<AppIdentityDbContext>()));
    return manager;
}

修改 Startup 类的上下文注册逻辑:

public void Configuration(IAppBuilder app)
{
    app.CreatePerOwinContext(AppIdentityDbContext.Create);
    app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);
    // 其余原有Cookie配置保持不变
}

步骤5:修复注册按钮逻辑

从 OWIN 上下文获取已经配置好的 AppUserManager,不要自行实例化 UserStore:

protected void CreateUser_Click(object sender, EventArgs e)
{
    var manager = Context.GetOwinContext().GetUserManager<AppUserManager>();
    var user = new IdentityUser() { UserName = UserName.Text };
    IdentityResult result = manager.Create(user, Password.Text);

    if (result.Succeeded)
    {
        StatusMessage.Text = string.Format("用户 {0} 创建成功!", user.UserName);
    }
    else
    {
        StatusMessage.Text = result.Errors.FirstOrDefault();
    }
}

步骤6:生成 Identity 相关表

在 Visual Studio 包管理器控制台执行以下命令,在 atish 数据库生成身份验证所需的表:

Enable-Migrations -ContextTypeName EmployeeService.AppIdentityDbContext -MigrationsDirectory Migrations\Identity
Add-Migration -ConfigurationTypeName EmployeeService.Migrations.Identity.Configuration InitialIdentity
Update-Database -ConfigurationTypeName EmployeeService.Migrations.Identity.Configuration

配置完成后,原有 Employee 业务逻辑走原来的 Database First 上下文,身份验证逻辑走独立的 Identity 上下文,互不影响。

方案2:合并上下文(不推荐)

如果一定要使用同一个上下文,需要手动修改自动生成的atishEntities代码:

  1. 删掉OnModelCreating方法里的throw new UnintentionalCodeFirstException();,添加base.OnModelCreating(modelBuilder);调用 Identity 的模型配置逻辑
  2. 把上下文构造函数绑定的连接字符串改成纯 SQLClient 类型,不要用带 metadata 的 EntityClient 连接字符串
  3. 后续每次更新 EDMX 都需要手动恢复上述修改,维护成本极高。

内容的提问来源于stack exchange,提问作者atish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 22:57:04