如何在单独的项目中配置Entity Framework?

How to configure Entity Framework in a separate project?

我有一个 ASP.NET MVC 应用程序 EducationalCenter 具有以下项目结构:

DbContext 文件是 Data 项目中的 EducationalCenterContext.cs 并且如下所示:

public sealed class EducationalCenterContext: DbContext
{
    public DbSet<Student> Students { get; set; }

    public EducationalCenterContext( DbContextOptions<EducationalCenterContext> options)
        : base(options)
    {
        Database.EnsureCreated();
    }
}

而在Startup.cs文件中,dbContext在ConfigureService()中配置如下:

services.AddDbContext<EducationalCenterContext>
                (options => options.UseSqlServer("Server=localhost;Database=EducationalCenterDb;Trusted_Connection=True;MultipleActiveResultSets=true"));

这是我的工作版本,我在尝试添加迁移时修复了错误。但是,我的 Web 应用程序对 Data 项目有项目引用,这对我来说似乎很糟糕。

我的第一个想法是什么:

appsettings.json 我创建了这个部分 :

"ConnectionStrings": {
    "DefaultConnection":  "Server=localhost;Database=EducationalCenterDb;Trusted_Connection=True;MultipleActiveResultSets=true" 
}

然后我在Common项目中创建了AppSettingsclass:

public class AppSettings
{
    public string ConnectionString { get; set; }
}

然后我尝试通过 DI 在 DAL 中传递 ConnectionString:

services.Configure<AppSettings>(Configuration.GetSection("ConnectionStrings"));

并创建了 EducationalDbContext.cs:

public sealed class EducationalCenterContext: DbContext
{
    private readonly string _connectionString;

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

    public EducationalCenterContext( IOptions<AppSettings>, DbContextOptions<EducationalCenterContext> options)
        : base(options)
    {
        _connectionString = app.Value.ConnectionString;
        Database.EnsureCreated();
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(_connectionString);
    }
} 

但是当我尝试通过 PM 控制台 add-migration 时,我 运行 出现了这个错误:

Could not load assembly 'EducationalCenter.Data'. Ensure it is referenced by the startup project 'EducationalCenter'

然后我在下一个错误中添加了项目引用和运行:

Unable to create an object of type 'EducationalCenterContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

然后我在Startup.cs中添加了services.AddDbContext<>,就得到了我上面提到的工作版本。

所以...

  1. 我的网络应用程序引用了数据访问项目是否正常?
  2. 能否在Data项目中配置EF,保证DAL、BLL和web app正常分离?

将上下文和配置放在单独的项目中就可以了。

您遇到第一个错误是因为“教育中心”被设置为启动项目但没有引用数据项目。

第二个错误是因为迁移生成器需要数据项目中的一些连接信息来解析连接(比较 EF 状态和数据库状态)以确定需要进行哪些更改。

首先在您的数据项目中添加引用:

Microsoft.EntityFrameworkCore.Design

然后在迁移控制台命令将发现的数据项目中添加上下文工厂:

internal class MyContextFactory : IDesignTimeDbContextFactory<MyContext>
{
    public MyContext CreateDbContext(string[] args)
    {
        var dbContextBuilder = new DbContextOptionsBuilder<MyContext>();
        var connString = "myconnection string";
        dbContextBuilder.UseSqlServer(connString);
        return new MyContext(dbContextBuilder.Options);
    }
}