2017-01-22 212 views
1

有你在我的解決方案兩個項目如下:EF核心1.1 - 如何添加遷移在.NET核心控制檯

  • Sample.UI:通過創建一個DOTNET核心控制檯項目「的dotnet新」 。
  • Sample.Infrastruction:由「dotnet new -t lib」創建的dotnet核心庫,BlogDbContext就在那裏。

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

No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.On Configuring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext

錯誤堆棧信息:

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

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

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

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

at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)

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

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.b__0()

at 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" 

回答

3

要在做EF Core遷移時避免最常見的錯誤,做fo llowing

  1. 明確寫入命令
    --startup項目< startproject命令>,樣品的項目參數。UI在你的情況
    --project < ContextProject>,這是你的DbContext葉,Sample.Infrastructure你的情況

  2. 遷移與public default constructorIDbContextFactory工作,如果默認是absent.So如果使用默認的項目構造函數,你必須在你的上下文類重寫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); 
    } 
} 

alternativly可以實現IDbContextFactory在您的BlogDbContext所在的同一個項目中

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); 
    } 
} 
+0

謝謝@nsb,我喜歡Factory解決方案。它不會污染我的BlogDbContext。 – Charlie

+1

optionsBuilder.UseSqlite(Configuration [「ConnectionString」]);不再工作了。請更新 –

0

您需要添加Sample.Infrascruture作爲--project。就像這樣:

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

再從Sample.UI項目

相同的運行它,當你做一個database upgrade

另外,儘量設置的ConnectionString在BlogDbContext

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

我試過了你的方式,但它引發了同樣的錯誤。你成功了嗎? – Charlie

+0

@Charley是的,這是我的方式。我在這個問題上用了幾個小時。 –

+0

我已更新問題以包含一些錯誤堆棧信息。以及關於您的解決方案的反饋。你能幫我看一下嗎?如果你需要任何其他信息,請告訴我。 – Charlie