【发布时间】: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。
以下是一些关键代码:
-
在名为 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中的代码完全一样,所以我跳过了。
-
下面是来自 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 自己的属性之一(或其他库需要)。
-
在 global.cs 中
protected void Application_Start() { //... MFCCorporationDbFactory.CorporationDbContext = new ScrumDbContext(); MFCTeamDbFactory.TeamDbContext = new ScrumDbContext(); ScrumDbContextInitializer.Seed(); }
可能的问题: 通过单个静态 dbContext 访问实体可能会导致冲突。如果是这样,我将更新上面的代码。
【问题讨论】:
标签: entity-framework ef-code-first dbcontext