【问题标题】:Unable to create an object of type 'DbContext'无法创建“DbContext”类型的对象
【发布时间】:2019-06-20 12:32:50
【问题描述】:

当我尝试运行时

dotnet ef migration add Init

我收到错误

无法创建“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>();
}

现在看起来像这样。

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

和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());
}

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

我的 Startup.cs 中有 ofc

services.AddEntityFrameworkNpgsql().AddDbContext<IdentityContext>(options =>
    options.UseNpgsql(Configuration.GetConnectionString("IdentityConnection")));

编辑 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();
    }
  }

编辑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

【问题讨论】:

  • 我一直使用这样的 postgres 注册 db 上下文:services.AddDbContext&lt;IdentityContext&gt;(options =&gt; options.UseNpgsql(Configuration.GetConnectionString("IdentityConnection"))); 你能试试看它是否有效吗?
  • 同样的错误。无法创建“IdentityContext”类型的对象。
  • 您是否调试并检查启动类是否被正确调用?
  • 如果你改变这个怎么办:var webHostBuilder = WebHost.CreateDefaultBuilder() .UseConfiguration(config) .UseStartup&lt;TStartup&gt;(); return new HostBuilder(webHostBuilder.Build()); for return WebHost.CreateDefaultBuilder() .UseConfiguration(config) .UseStartup&lt;TStartup&gt;();
  • @carloschourio 我调试了,没有发现任何问题。

标签: c# entity-framework asp.net-core


【解决方案1】:

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

【讨论】:

  • 你先生,是一个该死的壁架:)
  • 还在包管理器控制台中将默认项目设置为数据项目,这对我有帮助
【解决方案2】:

确保你有没有参数的 IdentityContext 默认构造函数。它应该可以工作。

【讨论】:

  • 看似简单,但我经常忘记这一点(通常将选项传递给唯一的构造函数)。
  • 惊讶地发现带有默认参数的构造函数不算作无参数构造函数。这不起作用: public HumbleDbContext(string connectionString = "Server=.;Database=MyDb;Trusted_Connection=True;")
【解决方案3】:

似乎您实现了 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

【讨论】:

  • 我附加了 IdentityContext 类。它的扩展 DbContext。正如我所说,它在我更改 Startup.cs 之前有效,所以我认为它已正确实施。最后在这部分。
  • 我看到在旧启动中您将参数传递给 CreateWebHostBuilder 而在 ServiceHost 中您没有传递它。
  • 你使用的是哪个 dot net core 版本?
  • # dotnet --version # 2.2.105
  • 尝试按照docs.microsoft.com/en-gb/ef/core/miscellaneous/cli/…codingblast.com/… 中的说明实现IDesignTimeDbContextFactory
【解决方案4】:

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

顶级语句:

Console.WriteLine("Hello, World!");

经典Program类:

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

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

【讨论】:

  • 谢谢,节省了我很多时间! :d
【解决方案5】:

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

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

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

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

【讨论】:

    【解决方案6】:

    如果您使用的是 CLI,

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

    My_Solution
           |DataAccess_Project
           |-- DbContext.cs
           |WebApp_Project
           |-- Startup.cs
    

    进入解决方案目录

    CD My_Solution

    dotnet ef add migration InitialCreate --project DataAccess_Project --startup-project WebApp_Project

    dotnet ef database update --project DataAccess_Project --startup-project WebApp_Project

    【讨论】:

    • 谢谢,不过倒过来。第一个应该是dotnet ef migrations add....
    • 这正是我的问题。谢谢。
    【解决方案7】:

    添加此解决方案的变体以防它对某人有所帮助。我需要在一个简单的控制台应用程序中创建迁移,并且必须向 DbContext 类添加一个空的默认 .ctor。

    public TestContext()
    {
    }
    
    public TestContext(DbContextOptions<TestContext> options) : base(options)
    {
    }
    

    【讨论】:

    • 这为我解决了这个问题,我以为它正在尝试重新创建我的上下文类,但它实际上是在尝试实例化它。
    【解决方案8】:

    EF 需要能够获取 DbContext 的实例。

    来自an answer here

    确保将默认启动项目设置为 WebApplication
    然后在包管理器控制台中将默认项目设置为 数据项目。这将使用 WebApplication 配置并添加 迁移到 Data 项目。

    如果您正在运行 update-database 命令,则需要将默认项目设置为 Startup.cs 文件所在的 WebAPI 项目。

    【讨论】:

      【解决方案9】:

      在我的情况下,问题是启动没有被检测到它在程序中设置的方式:

      public static IWebHostBuilder CreateWebHostBuilder(string[] args, Type startup)
      {
         return WebHost.CreateDefaultBuilder(args).UseStartup(startup);
      }
      

      传递类型直接解决问题:

      .UseStartup<Startup>()
      

      【讨论】:

        【解决方案10】:

        它可能会给您这个问题,因为您使用的是分层架构。所以你必须工厂设计模式。例如你的上下文类必须像下面这样;

             public ModelContext(DbContextOptions<ModelContext> options) : base(options){}
        
               public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<ModelContext>
            {
        
                        DbContextOptionsBuilder<ModelContext> builder = new DbContextOptionsBuilder<ModelContext>();               
                        IConfiguration config = new ConfigurationBuilder()
                        .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(),"C:/Users/mücteba/source/repos/market/Market.API")) 
                               
                        .AddJsonFile("appsettings.json")
                        .Build();
                   builder.UseSqlServer(config.GetConnectionString("SQLProvider"));
                    return new ModelContext(builder.Options);
             }
          }
              DbSet<Personel> personels { get; set; }
        

        如果你使用分层架构,这个类是必需的!!!!

        【讨论】:

          【解决方案11】:

          在您的类中使用DbContext 将构造函数设置为:

          public class NameContext: DbContext
          {
              public NameContext(DbContextOptions<NameContext> options) : base(options)
              { }
          }
          

          资源:
          https://docs.microsoft.com/en-us/ef/core/dbcontext-configuration/

          【讨论】:

            【解决方案12】:

            在我的情况下,问题的原因是 dbsettings.json 文件的路径不正确。 这个路径应该写在 Startup.cs 文件中。

             public Startup(Microsoft.AspNetCore.Hosting.IHostingEnvironment hostEnv)
                {
                    _confString = new ConfigurationBuilder().SetBasePath(hostEnv.ContentRootPath).AddJsonFile("dbsettings.json").Build();
                
                }
            

            【讨论】:

              猜你喜欢
              • 2020-11-09
              • 2021-06-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-03-20
              • 2021-02-06
              • 2021-08-15
              相关资源
              最近更新 更多