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

.NET Core7项目集成Identity:现有EF Core上下文冲突解决问询

在现有EF Core项目中集成Identity的问题

我有一个基于.NET Core 7、使用EF Core的应用,里面已经有多个经过测试的可用实体。现在要给它添加Identity功能,还要让AspNetUsers和部分现有实体建立关联,当前数据库里没有任何Identity相关的表。

按照官方教程操作时,需要指定数据库上下文和用户上下文。我选了数据项目里的EventFinderContext(与Web应用同解决方案不同项目),并创建了新的用户上下文。脚手架生成完成后,出现重复的EventFinderContext类,导致模糊引用错误;尝试将两个类改为partial后,执行迁移又提示存在多个DbContext,必须指定要使用的上下文。

有建议从头新建包含Identity的项目,但工作量太大。现提出两个问题:

  1. 需要修改哪些内容才能让脚手架适配现有EF Core逻辑?
  2. Identity是否应该使用独立的专用上下文?考虑到要建立Identity实体与现有实体的关联,这看起来不太合理。

更新:添加Identity后的代码结构

数据项目(包含实体和迁移)

EventFinderContext.cs

namespace EventFinderData
{
    public class EventFinderContext : DbContext
    {
        public DbSet<EventItem> EventItems { get; set; }
        public DbSet<EventCategory> EventCategories { get; set; }

        public EventFinderContext(DbContextOptions<EventFinderContext> options) : base(options) 
        {
        }

    }
}

Web应用项目 - VS/Identity生成的类

Areas\Identity\Data\EventFinderWebAppRazorContext.cs

namespace EventFinderWebAppRazor.Data;
public class EventFinderWebAppRazorContext : IdentityDbContext<EventFinderWebAppRazorUser>
{
    public EventFinderWebAppRazorContext(DbContextOptions<EventFinderWebAppRazorContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }
}

Areas\Identity\Data\EventFinderWebAppRazorUser.cs

namespace EventFinderWebAppRazor.Areas.Identity.Data;

public class EventFinderWebAppRazorUser : IdentityUser
{
}

Program.cs

builder.Services.AddDbContextFactory<EventFinderContext>(options =>
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("EventFinderConnString"), 
        ss => ss.UseNetTopologySuite())
    .EnableSensitiveDataLogging());

builder.Services.AddDefaultIdentity<EventFinderWebAppRazorUser>(
    options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<EventFinderWebAppRazorContext>();

解答

问题1:修改内容适配现有EF Core逻辑

核心问题是两个独立DbContext导致冲突,正确做法是将Identity集成到现有EventFinderContext中,步骤如下:

  1. 修改现有上下文的继承关系
    将EventFinderContext从DbContext改为继承IdentityDbContext<EventFinderWebAppRazorUser>,并确保能访问用户实体类:

    // 数据项目中的EventFinderContext.cs
    using EventFinderWebAppRazor.Areas.Identity.Data;
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
    
    namespace EventFinderData
    {
        public class EventFinderContext : IdentityDbContext<EventFinderWebAppRazorUser>
        {
            public DbSet<EventItem> EventItems { get; set; }
            public DbSet<EventCategory> EventCategories { get; set; }
    
            public EventFinderContext(DbContextOptions<EventFinderContext> options) : base(options) 
            {
            }
    
            protected override void OnModelCreating(ModelBuilder builder)
            {
                base.OnModelCreating(builder); // 必须调用,否则Identity表无法生成
                // 保留原有模型配置(如果有)
            }
        }
    }
    
  2. 删除自动生成的Identity上下文
    直接删除Web项目中的EventFinderWebAppRazorContext.cs,统一使用数据项目的上下文。

  3. 调整Program.cs的服务配置
    让Identity使用现有EventFinderContext:

    // Program.cs
    builder.Services.AddDbContextFactory<EventFinderContext>(options =>
        options.UseSqlServer(
            builder.Configuration.GetConnectionString("EventFinderConnString"), 
            ss => ss.UseNetTopologySuite())
        .EnableSensitiveDataLogging());
    
    builder.Services.AddDefaultIdentity<EventFinderWebAppRazorUser>(
        options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<EventFinderContext>(); // 改为使用EventFinderContext
    
  4. 生成并执行Identity迁移
    打开包管理器控制台,指定数据项目为启动项目,执行以下命令:

    Add-Migration AddIdentityToExistingContext -Context EventFinderContext
    Update-Database -Context EventFinderContext
    

    此操作会将Identity相关表添加到现有数据库,同时保留原有实体表。

问题2:Identity是否需要独立上下文?

不需要,除非项目有特殊架构需求(如多数据库分离)。

当需要建立Identity用户与现有实体的关联时(比如用户创建的EventItem),共享上下文是最优方案:

  • 可直接在现有实体中添加用户导航属性与外键:
    public class EventItem
    {
        // 原有属性
        public int Id { get; set; }
        public string Title { get; set; }
    
        // 关联用户
        public string CreatorId { get; set; }
        public EventFinderWebAppRazorUser Creator { get; set; }
    }
    
  • 共享上下文能保证事务一致性,例如创建EventItem与更新用户信息可在同一事务中完成。

使用独立上下文会增加跨上下文关联的复杂度,还会导致事务管理困难,完全没必要。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:35:17