根据分裂DbContext

时间:2017-12-13 11:28:38

标签: c# entity-framework .net-core dbcontext

我想将我的DbContext类分成几部分,这样每个模块都有自己的类,我认为这样可以使工作更容易,错误更多,并降低代码复杂性。

我相信我在过去的某个地方看到它,但谷歌搜索却没有找到它的运气。

我的DbContext位于Infrastructure Layer中,而我的类位于域上下文中。那不是问题。我想将映射和配置分成不同的类。我的DbContext将保持不变,但会被拆分。

我标记了代码和平,我愿意分成以下部分:

public class WestCoreDbContext : DbContext
{
    public WestCoreDbContext(DbContextOptions<WestCoreDbContext> options) : base(options)
    {

    }
    #region WOULD LIKE TO SPLIT THIS PART
    public virtual DbSet<SoftwareTest> SoftwareTests { get; set; }
    public virtual DbSet<SoftwareTestCase> SoftwareTestCases { get; set; }
    public virtual DbSet<SoftwareTestCaseStep> SoftwareTestCaseSteps { get; set; }
    public virtual DbSet<SoftwareTestCaseStepResult> SoftwareTestCaseStepResults { get; set; }

    public virtual DbSet<Position> Positions { get; set; }
    #endregion

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        #region WOULD LIKE TO SPLIT THIS PART
        SoftwareTestMapping(modelBuilder);
        SoftwareTestCaseMapping(modelBuilder);
        SoftwareTestCaseMapping(modelBuilder);
        SoftwareTestCaseStepMapping(modelBuilder);
        SoftwareTestCaseStepResultsMapping(modelBuilder);
        PositionMapping(modelBuilder);

        RelationshipsMapping(modelBuilder);
        #endregion

        modelBuilder.MyOracleNamingConventions();

        base.OnModelCreating(modelBuilder);
    }

    #region WOULD LIKE TO SPLIT THIS PART

    private void SoftwareTestMapping(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SoftwareTest>();
    }

    private void SoftwareTestCaseMapping(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SoftwareTestCase>();
    }

    private void SoftwareTestCaseStepMapping(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SoftwareTestCaseStep>();
    }

    private void PositionMapping(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Position>();
    }

    private void SoftwareTestCaseStepResultsMapping(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SoftwareTestCaseStepResult>();
    }

    private void RelationshipsMapping(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SoftwareTest>().HasMany(x => x.SoftwareTestCases).WithOne(op => op.SoftwareTest).IsRequired().HasForeignKey(@"StId");
        modelBuilder.Entity<SoftwareTestCase>().HasOne(x => x.SoftwareTest).WithMany(op => op.SoftwareTestCases).IsRequired().HasForeignKey(@"StId");

        modelBuilder.Entity<SoftwareTestCase>().HasMany(x => x.SoftwareTestCaseSteps).WithOne(op => op.SoftwareTestCase).IsRequired().HasForeignKey("StcId");
        modelBuilder.Entity<SoftwareTestCaseStep>().HasOne(x => x.SoftwareTestCase).WithMany(op => op.SoftwareTestCaseSteps).IsRequired().HasForeignKey("StcId");

        modelBuilder.Entity<SoftwareTestCaseStep>().HasMany(x => x.SoftwareTestCaseStepResults).WithOne(op => op.SoftwareTestCaseStep).IsRequired().HasForeignKey("StcsId");
        modelBuilder.Entity<SoftwareTestCaseStepResult>().HasOne(x => x.SoftwareTestCaseStep).WithMany(op => op.SoftwareTestCaseStepResults).IsRequired().HasForeignKey("StcsId");
    }
    #endregion

    public bool HasChanges()
    {
        return ChangeTracker.Entries().Any(e => e.State == EntityState.Added || e.State == EntityState.Modified || e.State == EntityState.Deleted);
    }

    ...
}
}

我不知道拆分DbContext的确切方法。 我需要一种方法来做到这一点。你能给我解决方案吗?

1 个答案:

答案 0 :(得分:3)

您首先要明确分割DbContext的意思。你说它是一个关注点分离问题,所以你应该首先决定你想要分开哪些问题。 DbContext处理将数据库表映射到对象模型的问题,因此它可以完成与此相关的所有操作。关注点分离的另一端是不将问题分成几部分,因为这也会增加程序的复杂性。

关注点的良好分离是将DbContext保持在一起并让它完成将数据库映射到对象模型的基本工作。其他任务(如对数据库的专门查询)将封装在使用DbContext的存储库中,这也允许您从实际的实体框架实现中抽象出业务层。

除此之外,还有一些方法可以将DbContext分成几部分:

使DbContext成为部分类

您可以将WestCoreDbContext设为partial class并将其内容拆分为多个代码文件。您应该清楚,虽然编译后的输出将完全相同,因此您无法真正改善OOP意义上的关注点分离。如果没有充分的理由(例如,部分自动生成的类)将单个类拆分为多个代码文件,实际上会增加或减少代码的可管理性。这是你必须为自己做出的决定。

使用实体类型配置类

您可以使用从EntityTypeConfiguration派生的类(或在.net Core 2.0中实现IEntityTypeConfiguration interface)使用流程API配置您的实体类,这样您就可以在{{{{}}之外配置实体类。 1}}。当你有更多的实体类时,这实际上可以帮助管理,DbContext方法会变得很长。

在你的情况下,这将在.net Core 2.0中看起来像这样(我简化了你的例子):

OnModelCreating

如果您不在.net Core 2.0上,请检查this Q&A以获得相同的结果。