簡體   English   中英

無法創建類型為“DbContext”的 object

[英]Unable to create an object of type 'DbContext'

當我嘗試跑步時

dotnet ef migration add Init

我收到錯誤

無法創建“IdentityContext”類型的 object。

我知道是什么導致了這個問題。 我想學習使用消息總線並將其添加到我的項目中,所以我參加了一些課程並實現了它。 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 class

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 中有

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

編輯 IdentityContext class:

  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

我的問題是我沒有將解決方案中的 api 項目設置為 Startup Project,因此它找不到任何 Startup.cs 或類似的東西。

如果您使用的是 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

確保您有沒有參數的 IdentityContext 的默認構造函數。 它應該工作。

似乎您實現了 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

如果您使用的是新的 .NET 5 頂級代碼功能,那么這絕對是遷移失敗的原因。 Program類中使用頂級語句使 EF 工具無法訪問它,因為它既不包含命名空間也不包含類名。

頂級語句:

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

經典Program類:

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

如果是這種情況,那就回到經典模式。

在名為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 方法並在找不到任何內容時返回錯誤。

添加此解決方案的變體以防它對某人有所幫助。 我需要在一個簡單的控制台應用程序中創建遷移,並且必須向 DbContext 類添加一個空的默認 .ctor。

public TestContext()
{
}

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

EF 需要能夠獲取 DbContext 的實例。

這里的答案

確保將默認啟動項目設置為 WebApplication
然后在 Package Manager Console中將 Default Project 設置為 Data project 這將使用 WebApplication 配置並將遷移添加到 Data 項目。

如果您正在運行 update-database 命令,則需要將默認項目設置為 Startup.cs 文件所在的 WebAPI 項目。

只是添加當前信息,以防它對.Net 6 上的某人有所幫助。
在我使用 .Net 6 和 dotnet-ef 版本 '6.0.4' 的情況下,使其工作的唯一關鍵是確保無參數構造函數存在並公開,如下所示:

public TestContext()
{
}

我的問題是 VS Code 為我創建了一個受保護的構造函數。
我嘗試過的一些事情沒有任何區別:-

  • 如果您的控制台應用程序是否使用頂級語句,
  • 不需要有一個TestContext(options)構造函數。

在我的情況下,問題是沒有按照程序中設置的方式檢測到啟動:

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

傳遞類型直接解決了問題:

.UseStartup<Startup>()

它可能會給你這個問題,因為你正在使用分層架構。 所以你必須工廠設計模式。例如,你的上下文類必須如下所示;

     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; }

如果你使用分層架構,這個類是必需的!!!!

在使用DbContext的類中,將構造函數設置為:

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

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

在我的情況下,問題的原因是 dbsettings.json 文件的路徑不正確。 這個路徑應該寫在 Startup.cs 文件中。

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

改善尖叫的答案

我有一個如下的項目結構

解決方案

  • X.API
  • ...
  • ...
  • 十、存儲庫

我的遷移在 X.Repository 下,我的啟動項目是 X.Api。 在正確設置所有內容后,沒有任何代碼錯誤,我無法使用以下命令運行我的遷移

dotnet ef migrations add CreateABCTable 

應用尖叫建議的解決方案,我可以運行我的遷移。 我使用了下面的命令

dotnet ef migrations add CreateABCTable --project X.Repository.csproj --startup-project ../X.Api/X.Api.csproj

我得到了同樣的錯誤。

實體框架工具版本“6.0.1”比運行時“6.0.6”舊。 更新工具以獲取最新功能和錯誤修復。

我更新了軟件包並且它工作正常。

在 Program.cs 中,我在 builder.Services.AddDbContext 之前調用了 builder.Build() 只是在最后調用了 builder.Build() 它解決了問題

在我的情況下,我將 API 項目層設置為啟動。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM