简体   繁体   English

当ASP.net Identity与相同的DbContext正常工作时,为什么EF7表示我没有配置任何提供程序?

[英]Why does EF7 say I haven't configured any providers, when ASP.net Identity is working fine with the same DbContext?

I've just started work on an experimental project using ASP.net 5, MVC6 and Entity Framework 7. I have ASP.Net Identity working fine, but then tried to add some of my own data to the DbContext and hit this problem. 我刚刚开始使用ASP.net 5,MVC6和Entity Framework 7进行实验项目。我的ASP.Net Identity工作正常,但随后尝试将自己的一些数据添加到DbContext中并解决了这个问题。 EF7 reports: EF7报告:

An unhandled exception occurred while processing the request. 处理请求时发生未处理的异常。

InvalidOperationException: No database providers are configured. InvalidOperationException:没有配置数据库提供程序。 Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services. 在设置服务时,通过覆盖DbContext类或AddDbContext方法中的OnConfiguring来配置数据库提供程序。

Microsoft.Data.Entity.Internal.DatabaseProviderSelector.SelectServices(ServiceProviderSource providerSource) Stack Query Cookies Headers Microsoft.Data.Entity.Internal.DatabaseProviderSelector.SelectServices(ServiceProviderSource providerSource)堆栈查询Cookie头

InvalidOperationException: No database providers are configured. InvalidOperationException:没有配置数据库提供程序。 Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services. 在设置服务时,通过覆盖DbContext类或AddDbContext方法中的OnConfiguring来配置数据库提供程序。

Here's my configuration method: 这是我的配置方法:

    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);

        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.AddMvc();

        // Add application services.
        services.AddTransient<IEmailSender, AuthMessageSender>();
        services.AddTransient<ISmsSender, AuthMessageSender>();

        services.AddTransient<ApplicationUnitOfWork>(instance => new ApplicationUnitOfWork());
    }

ApplicationUnitOfWork is a façade over EF7 to reduce tight coupling. ApplicationUnitOfWork是EF7的立面,以减少紧密耦合。 Here's the whole thing so far: 到目前为止,这是整个过程:

public class ApplicationUnitOfWork : IUnitOfWork
    {
    readonly ApplicationDbContext dbContext;

    public ApplicationUnitOfWork()
        {
        dbContext = new ApplicationDbContext();
        Products = new ProductRepository(dbContext);
        }

    public void Dispose() { dbContext.Dispose(); }

    public IUserRepository Users { get; }

    public IRepository<SoftwareProduct> Products { get; }

    public async Task CommitAsync() { await dbContext.SaveChangesAsync(); }

    public void Cancel() { throw new NotImplementedException(); }
    }

Now when I run the web application, I am able to register a user account and log in and EF creates the database, creates the Identity tables and populates them with user data. 现在,当我运行Web应用程序时,我可以注册一个用户帐户并登录,EF可以创建数据库,创建Identity表并使用用户数据填充它们。 The products table is also created - so clearly at some level EF is able to use the ApplicationDbContext and find a provider which it uses to create the database and schema. 产品表也已创建-显然,在某种程度上,EF能够使用ApplicationDbContext并找到用于创建数据库和架构的提供程序。

However when I try to access my Products controller, which uses the ProductsRepository , EF complains - even though ApplicationDbContext is used in both cases and was used to create the database! 然而,当我尝试访问我的产品控制器,它使用ProductsRepository ,EF抱怨-即使ApplicationDbContext在这两种情况下使用,用于创建数据库!

So how come? 那怎么会 What's special about ASP.net Identity that it can somehow obtain a provider, but my own code can't? ASP.net Identity有什么特别之处,它可以某种方式获得提供程序,但是我自己的代码不能? What "magic incantation" am I missing? 我缺少什么“魔咒”?

its because you are newing it up instead of having it injected for you. 这是因为您正在更新它,而不是为您注入了它。 The one you are newing up hasn't been configured. 您要更新的一个尚未配置。 You should change your class to have it passed into the constructor. 您应该更改您的类以使其传递到构造函数中。

DbContext has more than one constructor and you are using the empty one which doesn't configure it. DbContext具有多个构造函数,并且您正在使用未配置的空构造函数。

Better to let it be injected by making your constructor like this: 最好让您的构造函数像这样注入它:

 public ApplicationUnitOfWork(ApplicationDbContext context)
 {
    dbContext = context;
    Products = new ProductRepository(dbContext);
 }

your code shows that ApplicationDbContext has been registered with the DI, Identity is using the injected one but you are not since you newed it up yourself with the parameterless constructor 您的代码显示ApplicationDbContext已在DI中注册,Identity正在使用注入的DI,但自从您使用无参数构造函数对它进行了自定义以来,您就没有这样做了。

you should also register your ApplicationUnitOfWork so it can be injected: 您还应该注册您的ApplicationUnitOfWork以便可以注入它:

services.AddScoped<ApplicationUnitOfWork, ApplicationUnitOfWork>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM