无法创建类型为 '[DBContext名称]' 的对象。针对设计时所支持的不同模式进行操作。

158

我正在Udemy上学习Mosh Hamedani的ASP.NET MVC课程。

在使用代码优先(Entity Framework)设计我的数据库时,我遇到了一个错误。

起初,我遇到了"未在程序集中找到DbContext"的错误。解决了这个问题后,另一个错误突然出现了。

下面的图片将展示您在添加迁移时发现的错误。我已经搜索过相同的错误,但徒劳无功。我已经苦苦挣扎了两个小时,但到目前为止什么都没解决。

请有人帮帮我。谢谢

无法创建类型为'Vidly_Context'的对象。有关设计时支持的不同模式,请参见https://go.microsoft.com/fwlink/?linkid=851728


在添加自己的DbContext构造函数(带有两个参数)后出现了类似的问题。应用程序是正常的,但迁移停止工作。 通过使用Dotnet工具@xspdf提供的信息更新EF(在使用5时使用3.1.5的奇怪原因),并将提到的构造函数替换为方法+硬编码的默认连接字符串(如果未设置)来修复。
dotnet tool update --global dotnet-ef

// following command show the most during migration build/run in cmd
// mind current dir is Migrations folder of (VS) startup project here
dotnet ef --startup-project ../ --verbose migrations add test

3.1.5 & 上下文激活错误

The Entity Framework tools version '3.1.5' is older than that of the runtime '5.0.0'. Update the tools for the latest features and bug fixes.
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider in assembly '...'...
Finding Microsoft.Extensions.Hosting service provider...
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
Finding DbContext classes in the project...
Found DbContext '...Context'.
Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create an object of type '...Context'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
 ---> System.InvalidOperationException: Unable to resolve service for type 'System.String' while attempting to activate '...'. (my additional parameter)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass13_4.<FindContextTypes>b__13()
   --- End of inner exception stack trace ---
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass13_4.<FindContextTypes>b__13()
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Unable to create an object of type '...Context'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

2
是的,现在它正在工作。需要将一段C#代码添加到启动文件中。 - OoMaR jOhUr
16
@OoMaRjOhUr,您可以添加一个回答,展示您添加的代码以使其正常工作,并接受该答案。这可能会帮助未来的某个人。 - tomRedox
尝试在调试模式下运行应用程序,看看在dbcontext被注入到di容器之前应用程序是否会抛出异常。我曾经遇到过同样的问题,是由于应用程序在"options.UseSqlServer(.)"之前抛出异常引起的。希望这可以帮到你。 - Dennis Kabugua
1
在 Program.cs 文件中,在 builder.Services.AddDbContext 代码行之后添加 "var app = builder.Build();" 这一行。 - Davud Seyfullayev
将所有从 AddSingleton 和 AddScoped 注册的服务临时重新注册为 AddTransient。这对我起作用了。 - Stefan Vukovic
显示剩余3条评论
12个回答

143

1- 确保将您的Web项目设置为设置为启动项目

2- 在包管理器控制台中,将您的数据访问层(如果有)设置为默认项目

3- 然后再次运行命令


29
值得一提的是,如果在使用 Rider 时没有“设置为启动项目”的选项,你可以在命令中使用“--startup-project”。 - scottdavidwalker
10
这会导致错误“您的启动项目'Web'没有引用Microsoft.EntityFrameworkCore.Design。”因此,关于关注点分离,我不希望我的Web项目了解EF的情况..... - JHBonarius
14
我遇到了一个完全不同的问题,导致出现了相同的错误。在运行Add-Migration命令时加上-verbose参数非常有用,因为它可以让你看到生成迁移文件失败的原因。在我的情况下,是因为DBContext缺少一个空构造函数。 - GeorgiG
有时候工具也可能过时了。 - c-sharp-and-swiftui-devni
1
工作得很顺利。谢谢。 - undefined
显示剩余6条评论

83

错误信息表明在设计时无法创建上下文。如果您在迁移命令中使用--startup-project标志(或-s)指定启动项目,则可以帮助命令以类似运行时创建上下文实例的方式在设计时创建上下文实例。

例如:

cd ./project_with_migrations_folder
dotnet ef --startup-project ../my_startup_project_path/ migrations add myMigration01

3
更新。第二个命令是使用启动项目标志的迁移命令示例。应该适用于任何迁移命令。在我看来,这比现有答案更好,因为它不需要更改您的代码。 - tonymayoral
4
加上--startup-project解决了我的问题,谢谢! - badsyntax
2
这对我也起作用了。我的连接字符串在appsettings.json中,它在我的主Web API项目中,与我的数据项目(其中dbcontext位于)分开。我正在我的数据项目中运行dotnet ef migrations add InitialCreate,并且它失败并报告原始帖子中的错误。一旦我添加了--startup-project和指向我的主Web API项目的路径,它就可以工作了。 - Andrew

53

我遇到了同样的问题。楼主提到他们需要在Startup.cs中添加代码。

https://go.microsoft.com/fwlink/?linkid=851728上有以下代码示例:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
        => services.AddDbContext<ApplicationDbContext>();
}

我的代码在ConfigureServices方法中缺少以下内容;

services.AddDbContext<ApplicationDbContext>();

在我的数据库上下文中添加了这个后,问题得到了解决。


23
在使用EF Core代码优先迁移时,我遇到了这个问题。在一个包含MVC项目和Blazor项目的.NET Core 3解决方案中,如果我将解决方案的启动项目设置为Blazor项目,则在使用add-migration时会出现错误,但是如果我将启动项目设置为MVC项目,则不会出现错误。通过阅读错误消息链接的文档页面并比较两个项目的startup.cs文件中的代码,我不确定为什么会出现这种情况,但是将启动项目暂时切换到MVC项目可以解决我的问题。

1
你的问题是否是由于MVC项目中有对Microsoft.EntityFrameworkCore.Design的引用,而Blazor项目中没有引用所导致的?我过去发现过这种情况。 - PTD
@PTD 我非常晚才尝试添加该引用,但对我来说并没有修复它。 - tomRedox

22

我因为appsettings.json中缺少逗号而遇到了这个错误

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=Leonardo-Notebook;Initial Catalog=MyDB;Integrated Security=True"
  }, // <- Comma missing here
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

4
我曾经遇到过类似的问题。作为建议,确保你的程序能够运行,或者至少在尝试修复“add-migrations”问题之前能够启动。 - Miguel Hughes
同样在这里。谢谢...感觉很愚蠢。 - sk2andy

13
这不是框架的问题,而是你构建应用程序的方式。例如,如果你使用了依赖注入,并且将WebApi(或MVC项目)与数据访问层分离,当你尝试添加迁移时,你的上下文无法找到你尝试注入的连接字符串(这实际上就是我的情况)。
GitHub上找到了一个很好的解释:
“这绝对不是此存储库中问题的范围,但我还是会尝试给你一些指导。
生成迁移时出现该错误,原因是你需要满足以下条件之一:
1. 有一个具有默认构造函数(即无参数构造函数)的DbContext 2. 能够从ApplicationServices获取DbContext(即依赖注入) 3. 有一个设计时工厂,返回配置正确的DbContext
由于ApplicationDbContext构造函数有一个参数,你必须使用选项2或3。请参阅文章中的详细信息:https://learn.microsoft.com/ef/core/miscellaneous/cli/dbcontext-creation 但原本使用的选项2现在不再起作用,因为程序启动已更改以改善日志记录。”

而且,由于 ApplicationDbContext 没有 DesignTimeFactory,你现在就无法创建迁移。

如果您想了解创建迁移的方法,可以尝试以下两种方式:

创建一个 ApplicationDbContextDesignTimeFactory(类似于 CatalogContextDesignFactory 或 IntegrationEventLogContextDesignTimeFactory),或者 尝试使用其他已经具有其 DesignTimeFactory 的微服务,例如 Catalog.API。


1
是的,这正是我的情况。我在迁移后添加了 DI,然后在设计时无法访问 DbContext。通过将选项移动到 DbContext 的 OnConfiguring 方法中,使 DbContext 成为无参数的,问题得以解决。 - Niksr

13

在将我的 DbContext 放入一个单独的类库中并使用 .NET Core 3.1 后,我遇到了这个错误。

最终的解决方案看起来像这样,并从我原始应用程序的 appsettings.json 中获取我的连接字符串:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace MyNamespace
{
    public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
    {
        public ApplicationDbContext CreateDbContext(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json")
                    .Build();

            var optionsBuilder = new DbContextOptionsBuilder();

            var connectionString = configuration
                        .GetConnectionString("DefaultConnection");

            optionsBuilder.UseSqlServer(connectionString);

            return new ApplicationDbContext(optionsBuilder.Options);
        }
    }
}

我随后可以像这样将其用于我的另一个项目:

var applicationDbContextFactory = new ApplicationDbContextFactory();

using (var dbContext = applicationDbContextFactory.CreateDbContext(args))
{
    
}

在类库中配置一个DbContext和连接字符串的设置文件是不可能的吗? - Subliminal Hash
你是对的。在我的情况下,我只需注释掉“new ConfigurationBuilder()...”这一行,它就可以工作了。 - Ngọc Anh

9

在启动文件中的 ConfigureServices 方法中

services.AddDbContextPool<contextName>(
                    options => options.UseSqlServer(Configuration.GetConnectionString("conString")));

4
我正在使用完全相同的内容,但仍然出现错误。 - Shahriar Rahman Zahin
这对我很有用!"AddDbContextPool"和"AddDbContext"有什么不同? - undefined

5

这是你在ASP.NET Core中遇到的最荒谬的问题之一。我不确定你提到的课程,但如果你的应用程序就像我的,演示层与数据层是分离的,请确保你也在“启动项目”即演示层中安装了最新版本的Microsoft.EntityFrameworkCore.Design。它是必须的,而错误消息并没有提到。


有些晦涩。我选择了这个选项,一切都很好 - 谢谢。 - Scott Willis
在出现上述错误之前,我一直收到一个错误提示,说需要在API层中安装Microsoft.EntityFrameworkCore.Design包,但现在不再是这种情况了。 - Mocas

2

如果您正在使用像Azure SQL DB这样经过适当身份验证的数据库服务器,请检查是否在连接字符串中用您的服务器密码替换Password={your_password}


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