如何在单独的项目中配置实体框架?

时间:2021-07-24 10:31:10

标签: c# asp.net-mvc entity-framework architecture

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

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

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

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

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

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

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

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 时,我遇到了这个错误:

<块引用>

无法加载程序集“EducationalCenter.Data”。确保它被启动项目“EducationalCenter”引用

然后我添加了项目引用并遇到了下一个错误:

<块引用>

无法创建类型为“EducationalCenterContext”的对象。有关设计时支持的不同模式,请参阅 https://go.microsoft.com/fwlink/?linkid=851728

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

所以...

  1. 我的 Web 应用引用数据访问项目是否正常?
  2. 是否可以在 Data 项目中配置 EF 并确保 DAL、BLL 和 Web 应用程序之间正常分离?

1 个答案:

答案 0 :(得分:2)

将上下文和配置放在一个单独的项目中是可以的。

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

第二个错误是因为迁移构建器需要数据项目中的一些连接信息来解析连接(比较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);
    }
}