无法创建类型为“DbContext”的对象

Tho*_*hou 15 c# entity-framework asp.net-core

当我尝试跑步时

dotnet ef migration add Init
Run Code Online (Sandbox Code Playgroud)

我得到错误

无法创建类型为“IdentityContext”的对象。

我知道是什么导致了这个问题。我想学习使用消息总线并将其添加到我的项目中,所以我参加了一些课程并实施了它。Ofc 总线工作正常。但问题是我无法再通过 EF 进行迁移。

我之前的 Startup.cs 是。

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}
Run Code Online (Sandbox Code Playgroud)

现在看起来像这样。

public static void Main(string[] args)
{
  ServiceHost.Create<Startup>(args)
    .UseRabbitMq()
    .Build()
    .Run();
}
Run Code Online (Sandbox Code Playgroud)

和 ServiceHost 类

public void Run() => _webHost.Run();

public static HostBuilder Create<TStartup>(string[] args) where TStartup : class
{
  Console.Title = typeof(TStartup).Namespace;
  var config = new ConfigurationBuilder()
    .AddEnvironmentVariables()
    .AddCommandLine(args)
    .Build();
  var webHostBuilder = WebHost.CreateDefaultBuilder()
    .UseConfiguration(config)
    .UseStartup<TStartup>();

  return new HostBuilder(webHostBuilder.Build());
}
Run Code Online (Sandbox Code Playgroud)

所以有人会建议为什么迁移停止工作?对我来说,它看起来应该有效,但事实并非如此,我想我错了。

而且我在 Startup.cs 中有

services.AddEntityFrameworkNpgsql().AddDbContext<IdentityContext>(options =>
    options.UseNpgsql(Configuration.GetConnectionString("IdentityConnection")));
Run Code Online (Sandbox Code Playgroud)

编辑 IdentityContext 类:

  public class IdentityContext : DbContext
  {
    public IdentityContext(DbContextOptions<IdentityContext> options) : base(options)
    {
      while (!Debugger.IsAttached)
      {
        Thread.Sleep(100);
      }
    }
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
      modelBuilder.Entity<User>().HasIndex(user => user.Email).IsUnique();
      modelBuilder.Entity<User>().HasIndex(user => user.Username).IsUnique();
    }
  }
Run Code Online (Sandbox Code Playgroud)

编辑2。详细迁移

Using project '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/CrossX.Identity.csproj'.
Using startup project '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/CrossX.Identity.csproj'.
Writing '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/obj/CrossX.Identity.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/tmp/tmpCq3PQa.tmp /verbosity:quiet /nologo /home/msek/Projects/inz/CrossX/src/CrossX.Identity/CrossX.Identity.csproj
Writing '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/obj/CrossX.Identity.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/tmp/tmpR48yu8.tmp /verbosity:quiet /nologo /home/msek/Projects/inz/CrossX/src/CrossX.Identity/CrossX.Identity.csproj
dotnet build /home/msek/Projects/inz/CrossX/src/CrossX.Identity/CrossX.Identity.csproj /verbosity:quiet /nologo

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:01.17
dotnet exec --depsfile /home/msek/Projects/inz/CrossX/src/CrossX.Identity/bin/Debug/netcoreapp2.2/CrossX.Identity.deps.json --additionalprobingpath /home/msek/.nuget/packages --runtimeconfig /home/msek/Projects/inz/CrossX/src/CrossX.Identity/bin/Debug/netcoreapp2.2/CrossX.Identity.runtimeconfig.json /home/msek/.dotnet/tools/.store/dotnet-ef/2.2.2/dotnet-ef/2.2.2/tools/netcoreapp2.2/any/tools/netcoreapp2.0/any/ef.dll migrations add Init --assembly /home/msek/Projects/inz/CrossX/src/CrossX.Identity/bin/Debug/netcoreapp2.2/CrossX.Identity.dll --startup-assembly /home/msek/Projects/inz/CrossX/src/CrossX.Identity/bin/Debug/netcoreapp2.2/CrossX.Identity.dll --project-dir /home/msek/Projects/inz/CrossX/src/CrossX.Identity/ --language C# --working-dir /home/msek/Projects/inz/CrossX/src/CrossX.Identity --verbose --root-namespace CrossX.Identity
Using assembly 'CrossX.Identity'.
Using startup assembly 'CrossX.Identity'.
Using application base '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/bin/Debug/netcoreapp2.2'.
Using working directory '/home/msek/Projects/inz/CrossX/src/CrossX.Identity'.
Using root namespace 'CrossX.Identity'.
Using project directory '/home/msek/Projects/inz/CrossX/src/CrossX.Identity/'.
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider...
Finding IWebHost accessor...
No CreateWebHostBuilder(string[]) method was found on type 'CrossX.Identity.Program'.
No application service provider was found.
Finding DbContext classes in the project...
Found DbContext 'IdentityContext'.
Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create an object of type 'IdentityContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728 ---> System.MissingMethodException: No parameterless constructor defined for this object.
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean skipCheckThis, Boolean fillCache)
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass12_3.<FindContextTypes>b__13()
   --- End of inner exception stack trace ---
   at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass12_3.<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)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
   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 'IdentityContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
Run Code Online (Sandbox Code Playgroud)

小智 92

如果您使用的是 CLI,

当您的解决方案包含 2 个项目 API/WebApp 和一个 DataAcess 项目时,您可以在命令行中传递选项。

My_Solution
       |DataAccess_Project
       |-- DbContext.cs
       |WebApp_Project
       |-- Startup.cs
Run Code Online (Sandbox Code Playgroud)

切换到解决方案目录

CD My_Solution
Run Code Online (Sandbox Code Playgroud)
dotnet ef migrations add InitialCreate --project DataAccess_Project --startup-project WebApp_Project
Run Code Online (Sandbox Code Playgroud)
dotnet ef database update --project DataAccess_Project --startup-project WebApp_Project
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你,不过倒退了。第一个应该阅读“dotnet ef migrations add....” (2认同)

C. *_*iel 14

我的问题是我没有将解决方案中的 api 项目设置为 Startup Project,因此它找不到任何 Startup.cs 或类似的东西。

  • 先生,你真是个该死的壁架:) (2认同)
  • 还将默认项目设置为包管理器控制台中的数据项目,这对我有帮助 (2认同)

Sal*_*vaf 8

如果您使用新的 .NET 5 顶级代码功能,那么这肯定是迁移失败的原因。在类中使用顶级语句Program会使 EF 工具无法访问它,因为它既不包含命名空间也不包含类名。

顶层声明:

Console.WriteLine("Hello, World!");
Run Code Online (Sandbox Code Playgroud)

经典Program班:

namespace MyApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果是这样的话,那就回到经典模式吧。


JcM*_*y3r 7

似乎您实现了 IdentityContext,但在您的应用程序中的某处仍在尝试引用 DbContext。确保 Identitycontext 正在扩展 DbContext。

https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext

编辑:如https://docs.microsoft.com/en-gb/ef/core/miscellaneous/cli/dbcontext-creation 中所述实现了 IDesignTimeDbContextFactory


小智 6

在 Program 类中创建一个名为CreateWebHostBuilder的方法。将主方法主体移至该类并从 Main 方法调用该类。新的实施将是:

public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    ServiceHost.Create<Startup>(args)
                .UseRabbitMq()
                .Build()
                .Run();
Run Code Online (Sandbox Code Playgroud)

ef 工具会查找 CreateWebHostBuilder 方法并在找不到任何方法时返回错误。


小智 6

确保您具有不带参数的 IdentityContext 的默认构造函数。它应该工作。

  • 看似简单,但我经常忘记这一点(通常将选项传递给唯一的构造函数)。 (3认同)

Ahm*_*ler 6

改进尖叫的答案

我有一个如下所示的项目结构

解决方案

  • X.Api
  • ...
  • ...
  • 十、存储库

我的迁移位于 X.Repository 下,我的启动项目是 X.Api。正确设置所有内容后,没有任何代码错误,我无法使用以下命令运行迁移

dotnet ef migrations add CreateABCTable 

Run Code Online (Sandbox Code Playgroud)

应用尖叫建议的解决方案,我可以运行我的迁移。我使用了下面的命令

dotnet ef migrations add CreateABCTable --project X.Repository.csproj --startup-project ../X.Api/X.Api.csproj
Run Code Online (Sandbox Code Playgroud)