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

时间:2017-01-22 10:25:51

标签: .net-core entity-framework-core

我的解决方案中有两个项目如下:

  • Sample.UI :由“dotnet new”创建的dotnet核心控制台项目。
  • Sample.Infrastruction :由“dotnet new -t lib”创建的dotnet核心库,BlogDbContext就在那里。

当我尝试在 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()   在Microsoft.EntityFrameworkCore.Internal.LazyRef1.get_Value()

     

at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Vis   itScoped(ScopedCallSite scopedCallSite,ServiceProvider提供商)

     

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。我已经google了很多,但大多数解决方案用于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"

2 个答案:

答案 0 :(得分:4)

为了避免在执行 EF Core 迁移时出现大多数公共错误,请执行以下操作

  1. 在命令
    中明确写出项目参数 - 启动项目&lt;您的案例中的StartProject&gt; ,Sample.UI - 项目&lt; ContextProject&gt; ,这是您的DBContext离开的项目,您的案例中的Sample.Infrastructure

  2. 如果使用默认构造函数,
  3. 迁移可以使用public default constructorIDbContextFactory。如果使用默认构造函数,则必须覆盖上下文类中的OnConfiguring,例如

  4. 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);
        }
    }
    

答案 1 :(得分:0)

您需要将Sample.Infrascruture添加为--project。像这样:

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

然后从Sample.UI项目

运行它

执行database upgrade

时也一样

另外,尝试在BlogDbContext

中设置连接字符串
 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
 {
     optionsBuilder.UseSqlServer("Server=.;Database=MYDB;Integrated Security=True");
 }