可重用类库中的EF6 Code First DbContext

时间:2015-01-21 15:00:22

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

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

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

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

背景:Web应用程序被称为" Scrum"(是的,敏捷的scrum),有2个可重用的库叫做Team and 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;
    }
    
  2. 方法&#34; AllTeams&#34;显示了通过接口访问db的示例。没有直接引用任何DbContext。

    类库公司的代码完全一样,所以我跳过它。

    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; }
      
    2. 因此,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();
            }
        
      2. 可能出现的问题: 通过单个静态dbContext访问实体可能会导致实施。如果是这样,我将更新上面的代码。

1 个答案:

答案 0 :(得分:0)

抱歉,我自己找到了答案。 事实证明,在代码中:

        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来自另一个可重用的类库。

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