【问题标题】:EF6 CodeFirst DbContext in reusable class libraries可重用类库中的 EF6 CodeFirst DbContext
【发布时间】:2015-03-20 03:42:23
【问题描述】:

2015-01-22 这个问题自己解决了。我想在这里留下更多代码来展示它是如何工作的,并希望它可以帮助其他人。

就像这家伙想要的一样(EF code first: inherited dbcontext creates two databases),我也想为可重用的类库构建一个 DbContext 设计。

设计听起来像这样: 1、对于每个类库(dll、project),没有dbContext,只有一个接口,可以访问它需要的实体。 2. 对于每个 Web 应用程序(sln,解决方案),Web 应用程序中只有一个 DbContext(并且任何 Web 应用程序都希望重用这些库),它继承了所有接口。 3. 当应用程序启动时,Web 应用程序通过静态接口将 dbContext 实例传递给所有库(可能会导致一些多线程问题?),因此它们可以访问它们的实体。 4. web应用的dbContext负责db初始化和种子。

背景:Web 应用程序称为“Scrum”(是的,敏捷的 Scrum),有 2 个可重用的库,分别称为 Team 和 Corporation。

以下是一些关键代码:

  1. 在名为 MFCTeam 的类库中,有一个名为 Team 的实体:

    public partial class Team : LeveledItem
    {
        public static IEnumerable<Team> AllTeams(int? corporationId = null)
        {
            return MFCTeamDbFactory.TeamDbContext.Teams.Where(i => i.CorporationId == (corporationId??MFCSite.Corporation.CurrentCorporationId));
        }
    }
    public interface ITeamDbContext
    {
        DbSet<Team> Teams { get; set; }
    }
    
    public class MFCTeamDbFactory
    {
        public static ITeamDbContext TeamDbContext;
    }
    

方法“AllTeams”显示了通过接口访问 db 的示例。没有直接引用任何 DbContext。

类库Corporation中的代码完全一样,所以我跳过了。

  1. 下面是来自 Web 应用程序 Scrum 的代码:

    public class ScrumDbContext : DbContext, ITeamDbContext, ICorporationDbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            Database.SetInitializer(new ScrumDbContextInitializer());
            base.OnModelCreating(modelBuilder);
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            modelBuilder.Entity<LeveledItem>()
                .Map<Team>(m => m.Requires("Type").HasValue(ItemType.Team))
                .Map<Story>(m => m.Requires("Type").HasValue(ItemType.Story));
        }
    
        public DbSet<Team> Teams { get; set; }
        public DbSet<Corporation> Corporations {get; set; }
        public DbSet<Story> Stories { get; set; }
    

因此,ScrumDbContext 继承了这两个接口。 接口 ITeamDbContext 需要 DbSetTeams,接口 ICorporaitonDbContext 需要 DbSet Corporations,而 DbSetStories 是 ScrumDbContext 自己的属性之一(或其他库需要)。

  1. 在 global.cs 中

        protected void Application_Start()
        {
            //...
            MFCCorporationDbFactory.CorporationDbContext = new ScrumDbContext();
            MFCTeamDbFactory.TeamDbContext = new ScrumDbContext();
            ScrumDbContextInitializer.Seed();
        }
    

可能的问题: 通过单个静态 dbContext 访问实体可能会导致冲突。如果是这样,我将更新上面的代码。

【问题讨论】:

    标签: entity-framework ef-code-first dbcontext


    【解决方案1】:

    对不起,我自己找到了答案。 原来在代码中:

            public static IEnumerable<Team> AllTeams(int? corporationId = null)
            {
                return MFCTeamDbFactory.TeamDbContext.Teams.Where(i => i.CorporationId == (corporationId??MFCSite.Corporation.CurrentCorporationId));
            }
    

    MFCSite.Corporation.CurrentCorporationId 调用了另一个独立的 MFCCorporationDbContext 并导致了该问题。 MFCCorporationDbContext 来自另一个可重用的类库。

    现在我删除了该数据库上下文并使用相同的设计实现了它。它现在工作正常。 我更新了问题中的代码以显示它是如何工作的,并希望它可以成为类似问题的答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-21
      • 1970-01-01
      相关资源
      最近更新 更多