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

4 c# entity-framework-core ef-core-2.0

我有多个上下文,其中之一有效,但其他三个找不到。

\n\n

我在用着PM> Add-Migration InitialCreateLdapIdentity -context LdapIdentityDbContext<LdapUser, LdapUserRole> -verbose

\n\n

这是它的输出:

\n\n
Finding DbContext classes...\nFinding IDesignTimeDbContextFactory implementations...\nFinding application service provider...\nFinding BuildWebHost method...\nUsing environment \'Development\'.\nUsing application service provider from BuildWebHost method on \'Program\'.\nMicrosoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]\n  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.\nFound DbContext \'ApplicationIdentityDbContext<ApplicationUser, ApplicationUserRole>\'.\nFound DbContext \'LdapIdentityDbContext<LdapUser, LdapUserRole>\'.\nFound DbContext \'BlogIdentityDbContext<BlogUser, BlogUserRole>\'.\nFound DbContext \'CountriesDbContext\'.\nFinding DbContext classes in the project...\nMicrosoft.EntityFrameworkCore.Design.OperationException: No DbContext named \'LdapIdentityDbContext<LdapUser, LdapUserRole>\' was found.\n
Run Code Online (Sandbox Code Playgroud)\n\n

有趣的是,当我跑步Add-Migration InitialCreateCountries -context CountriesDbContext时,这就起作用了。

\n\n

我也尝试过不使用通用参数,Add-Migration InitialCreateLdapIdentity -context LdapIdentityDbContext但没有成功。

\n\n

我的Startup.cs包含这个:

\n\n
services\n        .AddDbContext<ApplicationIdentityDbContext<ApplicationUser, ApplicationUserRole>>(\n                options =>\n                {\n                    options.UseSqlServer(Configuration.GetConnectionString("Identity"));\n                })\n        .AddDbContext<LdapIdentityDbContext<LdapUser, LdapUserRole>>(\n                options =>\n                {\n                    options.UseSqlServer(Configuration.GetConnectionString("LdapIdentity"));\n                })\n        .AddDbContext<BlogIdentityDbContext<BlogUser, BlogUserRole>>(\n                options =>\n                {\n                    options.UseSqlServer(Configuration.GetConnectionString("BlogIdentity"));\n                })\n        .AddDbContext<CountriesDbContext>(\n                options =>\n                {\n                    options.UseSqlServer(Configuration.GetConnectionString("Countries"));\n                });\n\nservices\n        .AddApplicationIdentity<ApplicationUser, ApplicationUserRole>()\n        .AddEntityFrameworkStores<ApplicationIdentityDbContext<ApplicationUser, ApplicationUserRole>>()\n        .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<ApplicationUser>>()\n        .AddRoleStore<ApplicationRoleStore<ApplicationUser, ApplicationUserRole>>()\n        .AddUserStore<ApplicationUserStore<ApplicationUser, ApplicationUserRole>>()\n        .AddSignInManager<ApplicationSignInManager<ApplicationUser, ApplicationUserRole>>()\n        .AddUserManager<ApplicationUserManager<ApplicationUser, ApplicationUserRole>>()\n        .AddDefaultTokenProviders();\n\nservices\n        .AddLdapIdentity<LdapUser, LdapUserRole>()\n        .AddEntityFrameworkStores<LdapIdentityDbContext<LdapUser, LdapUserRole>>()\n        .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<LdapUser>>()\n        .AddUserStore<LdapUserWtore<LdapUser, LdapUserRole>>()\n        .AddSignInManager<LdapSignInManager<LdapUser, LdapUserRole>>()\n        .AddUserManager<LdapUserManager<LdapUser, LdapUserRole>>()\n        .AddDefaultTokenProviders();\n\nservices\n        .AddBlogIdentity<BlogUser, BlogUserRole>()\n        .AddEntityFrameworkStores<BlogIdentityDbContext<BlogUser, BlogUserRole>>()\n        .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<BlogUser>>()\n        .AddUserStore<BlogUserStore<BlogUser, BlogUserRole>>()\n        .AddUserManager<BlogUserManager<BlogUser, BlogUserRole>>()\n        .AddDefaultTokenProviders();\n
Run Code Online (Sandbox Code Playgroud)\n\n

我完全没有想法,特别是因为在详细日志中它明确表示它找到了上下文。

\n\n

有人有什么想法吗?

\n\n

编辑

\n\n

方法AddApplicationIdentity<\xe2\x80\xa6>AddLdapIdentity<\xe2\x80\xa6>AddBlogIdentity<\xe2\x80\xa6>是扩展方法,我在GithubServiceCollection上查看了 asp.net core 实现

\n\n

所以我的实现看起来像这样:

\n\n
public static IdentityBuilder AddApplicationIdentity<TUser, TUserRole>(\n        this IServiceCollection services, Action<IdentityOptions> setupAction = null)\n        where TUser : ApplicationUser, new()\n        where TUserRole : ApplicationUserRole\n    {\n        services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();\n        services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();\n        services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();\n        services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();\n        services.TryAddScoped<IRoleValidator<TUserRole>, RoleValidator<TUserRole>>();\n        services.TryAddScoped<IdentityErrorDescriber>();\n        services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();\n        services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TUserRole>>();\n        services.TryAddScoped<ApplicationUserStore<TUser, TUserRole>, ApplicationUserStore<TUser, TUserRole>>();\n        services.TryAddScoped<ApplicationIdentityDbContext<Identity.Models.ApplicationUser, ApplicationUserRole>, ApplicationIdentityDbContext<Identity.Models.ApplicationUser, ApplicationUserRole>>();\n        services.TryAddScoped<ApplicationUserManager<TUser, TUserRole>, ApplicationUserManager<TUser, TUserRole>>();\n        services.TryAddScoped<ApplicationSignInManager<TUser, TUserRole>, ApplicationSignInManager<TUser, TUserRole>>();\n        services.TryAddScoped<RoleManager<TUserRole>, AspNetRoleManager<TUserRole>>();\n\n        if (setupAction != null)\n        {\n            services.Configure(setupAction);\n        }\n\n        return new IdentityBuilder(typeof(TUser), typeof(TUserRole), services);\n    }\n\n    public static IdentityBuilder AddLdapIdentity<TUser, TUserRole>(\n        this IServiceCollection services, Action<IdentityOptions> setupAction = null)\n        where TUser : LdapUser, new()\n        where TUserRole : LdapUserRole\n    {\n        services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();\n        services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();\n        services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();\n        services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();\n        services.TryAddScoped<IRoleValidator<TUserRole>, RoleValidator<TUserRole>>();\n        services.TryAddScoped<IdentityErrorDescriber>();\n        services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();\n        services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TUserRole>>();\n        services.TryAddScoped<LdapUserStore<TUser, TUserRole>, LdapUserStore<TUser, TUserRole>>();\n        services.TryAddScoped<LdapIdentityDbContext<TUser, TUserRole>, LdapIdentityDbContext<TUser, TUserRole>>();\n        services.TryAddScoped<LdapUserManager<TUser, TUserRole>, LdapUserManager<TUser, TUserRole>>();\n        services.TryAddScoped<LdapSignInManager<TUser, TUserRole>, LdapSignInManager<TUser, TUserRole>>();\n        services.TryAddScoped<RoleManager<TUserRole>, AspNetRoleManager<TUserRole>>();\n\n        if (setupAction != null)\n        {\n            services.Configure(setupAction);\n        }\n\n        return new IdentityBuilder(typeof(TUser), typeof(TUserRole), services);\n    }\n\n    public static IdentityBuilder AddBlogIdentity<TUser, TUserRole>(\n        this IServiceCollection services, Action<IdentityOptions> setupAction = null)\n        where TUser : BlogUser, new()\n        where TUserRole : BlogUserRole\n    {\n        services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();\n        services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();\n        services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();\n        services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();\n        services.TryAddScoped<IRoleValidator<TUserRole>, RoleValidator<TUserRole>>();\n        services.TryAddScoped<IdentityErrorDescriber>();\n        services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();\n        services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TUserRole>>();\n        services.TryAddScoped<BlogUserStore<TUser, TUserRole>, BlogUserStore<TUser, TUserRole>>();\n        services.TryAddScoped<BlogIdentityDbContext<BlogUser, BlogUserRole>, BlogIdentityDbContext<BlogUser, BlogUserRole>>();\n        services.TryAddScoped<BlogUserManager<TUser, TUserRole>, BlogUserManager<TUser, TUserRole>>();\n        services.TryAddScoped<RoleManager<TUserRole>, AspNetRoleManager<TUserRole>>();\n\n        if (setupAction != null)\n        {\n            services.Configure(setupAction);\n        }\n\n        return new IdentityBuilder(typeof(TUser), typeof(TUserRole), services);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

的实现LdapIdentityDbContext是这样的:

\n\n
public class LdapIdentityDbContext<TUser, TRole> : IdentityDbContext<TUser, TUserRole, Guid>\n    where TUser : LdapUser\n    where TRole : LdapUserRole\n{\n    public LdapIdentityDbContext(DbContextOptions<LdapIdentityDbContext<TUser, TRole>> options)\n        : base(options)\n    {\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

小智 5

发现它,原来你不能在 IdentityDbContext 中使用类型参数。