【问题标题】:EF Core 1.1 - How to Add migrations in .net core consoleEF Core 1.1 - 如何在 .net 核心控制台中添加迁移
【发布时间】:2017-06-06 23:39:17
【问题描述】:

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

  • Sample.UI:由“dotnet new”创建的 dotnet core 控制台项目。
  • 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 的基本构造函数

错误堆栈信息:

在 Microsoft.EntityFrameworkCore.Internal.DatabaseProviderSelector.SelectServices() 在 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 提供者)

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

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

在 Microsoft.EntityFrameworkCore.Design.Internal.DesignTimeServicesBuilder.Build(DbContext 上下文)

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

在 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 动作)

我已尝试添加 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"

【问题讨论】:

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


    【解决方案1】:

    为避免在进行 EF Core 迁移时出现最常见的错误,请执行以下操作

    1. 在命令中显式写项目参数
      --startup-project ,Sample.UI 在你的情况下
      --project ,这是您的 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);
        }
    }
    

    【讨论】:

    • 谢谢@nsb,我喜欢工厂解决方案。它不会污染我的 BlogDbContext。
    • optionsBuilder.UseSqlite(Configuration["ConnectionString"]);不再工作了。请更新
    【解决方案2】:

    您需要将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");
     }
    

    【讨论】:

    • 我已经尝试过你的方法,但它引发了同样的错误。你成功了吗?
    • @Charley 是的,我就是这样做的。我在这个问题上用了几个小时。
    • 我已更新问题以包含一些错误堆栈信息。以及有关您的解决方案的反馈。你能帮我看看吗,如果你需要任何其他信息,请告诉我
    • @Charley 查看我的更新答案。另外,尝试删除您的无参数构造函数 BlogDbContext
    • 是的,这个解决方案可以成功添加迁移,但我不想在 dbContext 中硬编码数据库信息,因为我希望 Sample.UI 来决定哪个将使用一种 DB,例如SqlServer、SQLite 等
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    相关资源
    最近更新 更多