EF Core 1.1 - 如何在.net核心控制台中添加遷移

.net-core entity-framework-core

我的解決方案中有兩個項目如下:

  • Sample.UI :由“dotnet new”創建的dotnet核心控制台項目。
  • Sample.Infrastruction :由“dotnet new -t lib”創建的dotnet核心庫,BlogDbContext就在那裡。

當我嘗試運行dotnet ef --startup-project ..\sample.ui migrations add InitialDB ,在Sample.Infrastructure文件夾中dotnet ef --startup-project ..\sample.ui migrations add InitialDB ,它引發了一個錯誤:

沒有為此DbContext配置數據庫提供程序。可以通過重寫DbContext.On配置方法或在應用程序服務提供程序上使用AddDbContext來配置提供程序。如果使用AddDbContext,那麼還要確保您的DbContext類型在其構造函數中接受DbContextOptions對象並將其傳遞給DbContext的基礎構造函數

錯誤堆棧信息:

at Microsoft.EntityFrameworkCore.Internal.DatabaseProviderSelector.SelectServices()at Microsoft.EntityFrameworkCore.Internal.LazyRef1.get_Value()

在Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Vis itScoped(ScopedCallSite scopedCallSite,ServiceProvider provider)

在Microsoft.Extensions.DependencyInjection.ServiceProvider。<> c__DisplayClass16_0.b__0(ServiceProvider provider)

在Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider,Type serviceType)

在Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService [T](IServiceProvider提供程序)

在Microsoft.EntityFrameworkCore.Design.Internal.DesignTimeServicesBuilder.Build(DbContext context)

在Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name,String outputDir,String contextType)

at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name,String outputDir,String contextType)

在Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase。<> c__DisplayClass3_0`1.b__0()

在Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)

我試圖添加AddDbContext來解決問題,但對我沒用。也許我沒有正確使用內置DI。我搜索了很多,但大多數解決方案都用於asp.net核心而不是dotnet控制台。


供您參考,以下是Sample.Infrastructure源代碼:

namespace Sample.Infrastructure
{
    public class BlogDbContext : DbContext
    {
        public BlogDbContext(DbContextOptions<BlogDbContext> options)
            : base(options)
        {

        }

        public BlogDbContext()
        {
             //ATT: I also don't understand why ef requires the parameterless constructor
        }

        public DbSet<Blog> Blogs { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<Blog>().HasKey(post => post.Identity);
            base.OnModelCreating(builder);
        }
    }
}

Sample.UI源代碼:

namespace Sample.UI
{
    public class Program
    {
        static public IConfigurationRoot Configuration { get; set; }
        private static IServiceProvider _serviceProvider;

        public static void Main(string[] args)
        {
            var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
            Configuration = builder.Build();

            //setup DI
            _serviceProvider = new ServiceCollection()
                .AddDbContext<BlogDbContext>(o=> o.UseSqlite(Configuration["ConnectionString"]))
                .BuildServiceProvider();

            // PostApplicationService app = new PostApplicationService();
            // var ctx = _serviceProvider.GetService(typeof(BlogDbContext)) as BlogDbContext;   
            // app.Inital(ctx);

            Console.ReadLine();
        }
    }
}

更新

我也嘗試過@ Morten的解決方案,在Sample.UI文件夾中執行以下命令。但是,我得到了完全相同的錯誤。

dotnet ef --project "C:\SampleDDD\Sample.Infrastructure" --startup-project "C:\SampleDDD\Sample.UI"  migrations add "InitalDB"

一般承認的答案

要在執行EF Core遷移時避免大多數公共錯誤,請執行以下操作

  1. 在命令中顯式寫入項目參數
    --startup-project <StartProject> ,Sample.UI就像你的情況一樣
    --project <ContextProject> ,這是你的DBContext離開的項目,在你的情況下是Sample.Infrastructure

  2. 如果默認情況不存在,遷移將使用public default constructorIDbContextFactory如果使用默認構造函數,則必須在上下文類中重寫OnConfiguring ,類似於

public class BlogDbContext: DbContext 
{
   public DbSet<Blog> Blogs { get; set; }
   protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
   {
     string connStr = ConfigurationManager.ConnectionStrings["YourConnName"].ConnectionString;
     optionsBuilder.UseSqlite(connStr);
   }
}

或者,您可以在BlogDbContext所在的同一項目中實現IDbContextFactory

public class YourFactory : IDbContextFactory<BlogDbContext>
{
    public BlogDbContextCreate()
    {
        var optionsBuilder = new DbContextOptionsBuilder<BlogDbContext>();
        string connStr = ConfigurationManager.ConnectionStrings["YourConnName"].ConnectionString;
        optionsBuilder.UseSqlite(connStr);

        return new BlogDbContext(optionsBuilder.Options);
    }
}

熱門答案

您需要將Sample.Infrascruture添加為--project 。喜歡這個:

dotnet ef --project "C:\MYPATH\Sample.Infrastructure" --startup-project "C:\MYPATH\Sample.UI" migrations add "TXT"

然後從Sample.UI項目運行它

進行database upgrade

另外,嘗試在BlogDbContext設置connectionstring

 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
 {
     optionsBuilder.UseSqlServer("Server=.;Database=MYDB;Integrated Security=True");
 }


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因