【问题标题】:How to allow migration for a console application?如何允许迁移控制台应用程序?
【发布时间】:2020-10-04 04:20:15
【问题描述】:

在使用asp.net core和ef core时,调用add-migration init没有问题。但是当我在下面的控制台应用程序上应用相同的方法时,我收到一条错误消息:

无法创建“StudentContext”类型的对象。将“IDesignTimeDbContextFactory”的实现添加到项目中,或查看https://go.microsoft.com/fwlink/?linkid=851728 了解设计时支持的其他模式。

解决此问题的最简单方法是什么?

.net核心控制台应用项目如下:

appsettings.json

{
  "ConnectionStrings": {
    "Storage": "Data Source=storage.db"
  }
}

EFCore.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.0.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
  </ItemGroup>

</Project>

Student.cs

namespace EFCore.Models
{
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

StudentContext.cs

要求:我不想通过默认的无参数构造函数或OnConfiguring 方法对StudentContext 类中的连接字符串进行硬编码。

using Microsoft.EntityFrameworkCore;

namespace EFCore.Models
{
    public class StudentContext : DbContext
    {
        public StudentContext(DbContextOptions<StudentContext> options) : base(options) { }

        public DbSet<Student> Students { get; set; }
    }
}

程序.cs

using EFCore.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System.IO;

namespace EFCore
{
    class Program
    {
        static void Main(string[] args)
        {
            var configurationBuilder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

            IConfigurationRoot configuration = configurationBuilder.Build();
            string connectionString = configuration.GetConnectionString("Storage");

            DbContextOptionsBuilder<StudentContext> optionsBuilder = new DbContextOptionsBuilder<StudentContext>()
                .UseSqlite(connectionString);

            using (StudentContext sc = new StudentContext(optionsBuilder.Options))
            {

                sc.Database.Migrate();

                sc.Students.AddRange
                (
                    new Student { Name = "Isaac Newton" },
                    new Student { Name = "C.F. Gauss" },
                    new Student { Name = "Albert Einstein" }
                );

                sc.SaveChanges();
            }
        }
    }
}

【问题讨论】:

    标签: c# console-application entity-framework-core


    【解决方案1】:

    重要提示:不要将您的程序集命名为ef(或eFEfEF)以避免this exception

    苦苦挣扎了几个小时,我找到了如下解决方案:

    using EFCore.Models;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Design;
    using Microsoft.Extensions.Configuration;
    using System.IO;
    
    namespace EFCore
    {
        class Program : IDesignTimeDbContextFactory<StudentContext>
        {
            public StudentContext CreateDbContext(string[] args)
            {
                var configurationBuilder = new ConfigurationBuilder()
                  .SetBasePath(Directory.GetCurrentDirectory())
                  .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
    
                IConfigurationRoot configuration = configurationBuilder.Build();
                string connectionString = configuration.GetConnectionString("Storage");
    
                DbContextOptionsBuilder<StudentContext> optionsBuilder = new DbContextOptionsBuilder<StudentContext>()
                    .UseSqlite(connectionString);
    
                return new StudentContext(optionsBuilder.Options);
            }
    
            static void Main(string[] args)
            {
                Program p = new Program();
    
                using (StudentContext sc = p.CreateDbContext(null))
                {
                    sc.Database.Migrate();
    
                    sc.Students.AddRange
                    (
                        new Student { Name = "Isaac Newton" },
                        new Student { Name = "C.F. Gauss" },
                        new Student { Name = "Albert Einstein" }
                    );
    
                    sc.SaveChanges();
                }
            }
        }
    }
    

    希望对其他人也有用!

    【讨论】:

    • 我发现这很有帮助。如果 any1 想知道,如果您有多个 db 上下文,最好创建一个单独的类来实现 IDesignTimeDbContextFactory&lt;T&gt;,而不是让 Program 类实现它。
    • 这非常有用,为我节省了大量时间。非常感谢!
    猜你喜欢
    • 2015-08-24
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多