EF Core“找不到名为xxx的DbContext”

4
我有多个上下文,其中一个可以工作,但其他三个找不到。
我正在使用PM> Add-Migration InitialCreateLdapIdentity -context LdapIdentityDbContext<LdapUser,LdapUserRole> -verbose 这是它的输出:
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider...
Finding BuildWebHost method...
Using environment 'Development'.
Using application service provider from BuildWebHost method on 'Program'.
Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
  User profile is available. Using 'C:\Users\brech\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
Found DbContext 'ApplicationIdentityDbContext<ApplicationUser, ApplicationUserRole>'.
Found DbContext 'LdapIdentityDbContext<LdapUser, LdapUserRole>'.
Found DbContext 'BlogIdentityDbContext<BlogUser, BlogUserRole>'.
Found DbContext 'CountriesDbContext'.
Finding DbContext classes in the project...
Microsoft.EntityFrameworkCore.Design.OperationException: No DbContext named 'LdapIdentityDbContext<LdapUser, LdapUserRole>' was found.

有趣的是,当我运行Add-Migration InitialCreateCountries -context CountriesDbContext时,它可以正常工作。
我也尝试过不带泛型参数的Add-Migration InitialCreateLdapIdentity -context LdapIdentityDbContext,但没有成功。
我的Startup.cs包含以下内容:
services
        .AddDbContext<ApplicationIdentityDbContext<ApplicationUser, ApplicationUserRole>>(
                options =>
                {
                    options.UseSqlServer(Configuration.GetConnectionString("Identity"));
                })
        .AddDbContext<LdapIdentityDbContext<LdapUser, LdapUserRole>>(
                options =>
                {
                    options.UseSqlServer(Configuration.GetConnectionString("LdapIdentity"));
                })
        .AddDbContext<BlogIdentityDbContext<BlogUser, BlogUserRole>>(
                options =>
                {
                    options.UseSqlServer(Configuration.GetConnectionString("BlogIdentity"));
                })
        .AddDbContext<CountriesDbContext>(
                options =>
                {
                    options.UseSqlServer(Configuration.GetConnectionString("Countries"));
                });

services
        .AddApplicationIdentity<ApplicationUser, ApplicationUserRole>()
        .AddEntityFrameworkStores<ApplicationIdentityDbContext<ApplicationUser, ApplicationUserRole>>()
        .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<ApplicationUser>>()
        .AddRoleStore<ApplicationRoleStore<ApplicationUser, ApplicationUserRole>>()
        .AddUserStore<ApplicationUserStore<ApplicationUser, ApplicationUserRole>>()
        .AddSignInManager<ApplicationSignInManager<ApplicationUser, ApplicationUserRole>>()
        .AddUserManager<ApplicationUserManager<ApplicationUser, ApplicationUserRole>>()
        .AddDefaultTokenProviders();

services
        .AddLdapIdentity<LdapUser, LdapUserRole>()
        .AddEntityFrameworkStores<LdapIdentityDbContext<LdapUser, LdapUserRole>>()
        .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<LdapUser>>()
        .AddUserStore<LdapUserWtore<LdapUser, LdapUserRole>>()
        .AddSignInManager<LdapSignInManager<LdapUser, LdapUserRole>>()
        .AddUserManager<LdapUserManager<LdapUser, LdapUserRole>>()
        .AddDefaultTokenProviders();

services
        .AddBlogIdentity<BlogUser, BlogUserRole>()
        .AddEntityFrameworkStores<BlogIdentityDbContext<BlogUser, BlogUserRole>>()
        .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<BlogUser>>()
        .AddUserStore<BlogUserStore<BlogUser, BlogUserRole>>()
        .AddUserManager<BlogUserManager<BlogUser, BlogUserRole>>()
        .AddDefaultTokenProviders();

我已经没有任何想法了,尤其是因为在详细日志中明确指出它找到了上下文。
有人有什么想法吗?
编辑
方法AddApplicationIdentity<…>AddLdapIdentity<…>AddBlogIdentity<…>ServiceCollection上的扩展方法,我已经查看了Github上的asp.net核心实现。
所以我的实现看起来像这样:
public static IdentityBuilder AddApplicationIdentity<TUser, TUserRole>(
        this IServiceCollection services, Action<IdentityOptions> setupAction = null)
        where TUser : ApplicationUser, new()
        where TUserRole : ApplicationUserRole
    {
        services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
        services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
        services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
        services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
        services.TryAddScoped<IRoleValidator<TUserRole>, RoleValidator<TUserRole>>();
        services.TryAddScoped<IdentityErrorDescriber>();
        services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
        services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TUserRole>>();
        services.TryAddScoped<ApplicationUserStore<TUser, TUserRole>, ApplicationUserStore<TUser, TUserRole>>();
        services.TryAddScoped<ApplicationIdentityDbContext<Identity.Models.ApplicationUser, ApplicationUserRole>, ApplicationIdentityDbContext<Identity.Models.ApplicationUser, ApplicationUserRole>>();
        services.TryAddScoped<ApplicationUserManager<TUser, TUserRole>, ApplicationUserManager<TUser, TUserRole>>();
        services.TryAddScoped<ApplicationSignInManager<TUser, TUserRole>, ApplicationSignInManager<TUser, TUserRole>>();
        services.TryAddScoped<RoleManager<TUserRole>, AspNetRoleManager<TUserRole>>();

        if (setupAction != null)
        {
            services.Configure(setupAction);
        }

        return new IdentityBuilder(typeof(TUser), typeof(TUserRole), services);
    }

    public static IdentityBuilder AddLdapIdentity<TUser, TUserRole>(
        this IServiceCollection services, Action<IdentityOptions> setupAction = null)
        where TUser : LdapUser, new()
        where TUserRole : LdapUserRole
    {
        services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
        services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
        services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
        services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
        services.TryAddScoped<IRoleValidator<TUserRole>, RoleValidator<TUserRole>>();
        services.TryAddScoped<IdentityErrorDescriber>();
        services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
        services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TUserRole>>();
        services.TryAddScoped<LdapUserStore<TUser, TUserRole>, LdapUserStore<TUser, TUserRole>>();
        services.TryAddScoped<LdapIdentityDbContext<TUser, TUserRole>, LdapIdentityDbContext<TUser, TUserRole>>();
        services.TryAddScoped<LdapUserManager<TUser, TUserRole>, LdapUserManager<TUser, TUserRole>>();
        services.TryAddScoped<LdapSignInManager<TUser, TUserRole>, LdapSignInManager<TUser, TUserRole>>();
        services.TryAddScoped<RoleManager<TUserRole>, AspNetRoleManager<TUserRole>>();

        if (setupAction != null)
        {
            services.Configure(setupAction);
        }

        return new IdentityBuilder(typeof(TUser), typeof(TUserRole), services);
    }

    public static IdentityBuilder AddBlogIdentity<TUser, TUserRole>(
        this IServiceCollection services, Action<IdentityOptions> setupAction = null)
        where TUser : BlogUser, new()
        where TUserRole : BlogUserRole
    {
        services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
        services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
        services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
        services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
        services.TryAddScoped<IRoleValidator<TUserRole>, RoleValidator<TUserRole>>();
        services.TryAddScoped<IdentityErrorDescriber>();
        services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
        services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TUserRole>>();
        services.TryAddScoped<BlogUserStore<TUser, TUserRole>, BlogUserStore<TUser, TUserRole>>();
        services.TryAddScoped<BlogIdentityDbContext<BlogUser, BlogUserRole>, BlogIdentityDbContext<BlogUser, BlogUserRole>>();
        services.TryAddScoped<BlogUserManager<TUser, TUserRole>, BlogUserManager<TUser, TUserRole>>();
        services.TryAddScoped<RoleManager<TUserRole>, AspNetRoleManager<TUserRole>>();

        if (setupAction != null)
        {
            services.Configure(setupAction);
        }

        return new IdentityBuilder(typeof(TUser), typeof(TUserRole), services);
    }
}

LdapIdentityDbContext的实现如下:

public class LdapIdentityDbContext<TUser, TRole> : IdentityDbContext<TUser, TUserRole, Guid>
    where TUser : LdapUser
    where TRole : LdapUserRole
{
    public LdapIdentityDbContext(DbContextOptions<LdapIdentityDbContext<TUser, TRole>> options)
        : base(options)
    {
    }
}

既然您已经使用AddDbContext添加了LdapIdentityDbContextBlogIdentityDbContextApplicationIdentityDbContext,则在扩展方法中不需要再添加它们的范围版本(dbContext被添加为瞬态)。 - Balah
这没解决问题,之前我有一个来自另一个项目的身份数据库,一切都正常运作。但是我改变了连接字符串,使得我有了独立的数据库。当我想为这些独立的上下文创建迁移时,问题就开始出现了。所以我非常怀疑那不是问题所在,但还是谢谢你的建议,我会将其删除。 :-) - user4149157
1个回答

5

找到了,原来在IdentityDbContext中不能使用类型参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接