c# - EF 迁移应该去哪里,我的类库项目还是我的 ASP.NET 项目?

标签 c# asp.net entity-framework entity-framework-migrations

我的解决方案包含:

  • FooBarAsp,一个 asp 项目(为应用程序提供 UI)
  • FooBar,一个类库(应用程序)
  • FooBar.Tests,一个测试项目(测试应用程序)

FooBar 使用 EF 6 Code First,包含多个模型,以及一个 DataContext . FooBarAsp 使用 Microsoft 的身份框架进行用户身份验证,并且有一个 ApplicationDbContext .这两种情况都很好,并且按预期工作。 Global.asax.cs 应该执行 MigrateDatabaseToLatestVersion (正确的?)。 FooBar.Tests 应该执行 DropCreateDatabaseAlways并且不会关心迁移(对吧?)。

我应该在 FooBarAsp 还是 FooBar 中启用迁移?对于这两种情况?

在 FooBar 中运行 EnableMigrations 之后(只是为了好玩),我的 __MigrationHistory 表包含两个 InitialCreate 行,一个具有 ContextKey=FooBar.Models.DataContext,另一个具有 ContextKey=FooBarAsp.Models.ApplicationDbContext。所以他们都已经被追踪了?如果是这样,(因为我没有启用自动迁移),我是否需要显式运行both MigrateDatabaseToLatestVersion<DataContext>MigrateDatabaseToLatestVersion<ApplicationDbContext>在 Global.asax.cs 中?


编辑

为什么我不想移动ApplicationUser进入 FooBar 并合并 ApplicationDbContext进入DataContext ?

现货ApplicationUser ASP 附带的是一个单独的实体(和单独的 ApplicationDbContext ,恰好指向同一个数据库)。 ASP的ApplicationUser身份框架负责身份验证、注册、电子邮件验证、登录、注销、密码、密码强度、密码重置、双因素身份验证、cookie、 session 、来自 facebook/google 等来源的外部登录等。FooBar 不知道或关心其中的任何一个。 FooBar 的 User s 有一个用户名,和 ASP 的 ApplicationUser我们有一个用户名。当用户登录时,我只查找 Foobar 的 User通过用户名,这就是登录的人。所以当我创建一个新的 Blog (其中Blog是一个FooBar实体),作者是FooBar的User (不是 ApplicationUser )。最终结果是 FooBar 不是 Web/Desktop/Console/iPhone/Android 应用程序。它是一个库,任何这些东西都可以引用、交互并为其提供用户界面。关键是 FooBar 不会被任何这些用户界面污染或影响。

所以我不想动ApplicationUser进入 FooBar,因为它来自 Microsoft.AspNet.Identity 命名空间,而 FooBar 不知道也不关心 ASP.NET(或 WPF 或任何接口(interface)碰巧是什么)。

最佳答案

正如 John 在他的评论中所说,将所有 EF 代码移动到单独的类库中可能会很好地为您服务。我通常会为新的解决方案创建 Web、Domain、DataAccess 和 Test 项目,并在必要时进一步拆分它们。这为您提供了一些清晰的、基本的关注点分离。 Visual Studio Web 项目模板不提供这一点,因为它被设计为独立于单个项目中。

Visual Studio 的 Web 模板是小型项目的良好起点,但随着项目的增长,它很快就会变得一团糟。将网站(或多或少是您的表示层)、域模型和业务逻辑以及数据访问都放在同一个项目中并不是特别好的做法。通过在 Web 应用程序中留下您的用户模型和单独的 DbContext 来部分分离它们可能会使 IMO 更加困惑,特别是如果您的 ApplicationUser 将参与与来自您的域类库的模型。

我建议将您的 ApplicationUser 移动到包含您的域模型的类库中,并将您的 ApplicationDbContext 移动到 DataAccess 类库中。您可以更进一步,毫不费力地将您的两个 DbContext 合并为一个,除非您怀疑该项目将增长到足以需要多个 DbContext。在这一点上,您的迁移应该在哪里变得非常明显。除非您试图将其抽象化,否则您的 Initializer 将始终进入应用程序,在您的情况下是 FooBarAsp,因此您是正确的,Global.asax 是设置它的地方。

但是,如果这听起来对您没有吸引力并且您希望保持当前的项目结构,我认为您最好为 DbContext 配置迁移 是为了保持一致性。那时,您的 Web 项目 (FooBarAsp) 中会有一组迁移,用于继承自 IdentityDbContextApplicationDbContext 和另一组驻留在您的类中的迁移库(FooBar)。两者都需要在您的 Web 项目的 Global.asax.cs 中进行初始化。

根据 OP 的更新进行编辑:我可以看出您希望将 ASP.NET 相关引用保留在域层之外的愿望。如果不像您所做的那样将用户模型一分为二,基本上不可能避免这种情况发生。 This is something I asked about when VS2013 was still pre-RTM并且从来没有得到满意的答案,因为目前不可能有一个用户模型可以与不引入某些 ASP.NET 相关程序集的身份一起使用。但是,在有点类似的情况下,DbGeography 类型可以是包含在您的域层中的非常有用的类型,但如果不引入与 Entity Framework 相关的程序集,则无法使用它。这实际上归结为权衡利弊并在两害相权取其轻 - 在何时何地应用设计模式时要务实。

就是说,如果您确实希望在 Web 应用程序中将 DbContextApplicationUser 分开,我建议从应用程序用户——实际上,只需使用 IdentityUser 类本身而不是子类化它,因为您将纯粹使用它来进行身份验证和授权。但是,我相信您仍然需要为这两种情况启用迁移并研究如何使用 multiple contexts per database with EF6 ,这在 EF5 中是不可能的。

关于c# - EF 迁移应该去哪里,我的类库项目还是我的 ASP.NET 项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28974687/

相关文章:

c# - 无法将文件 ‘{0}' 作为数据库 '{1}' 附加。先写代码。本地 SQL EXPRESS 实例。 VS 2010 SP1。 window XP

c# - 使用 Entity Framework asp.net mvc登录流程

javascript - 如何使用 javascript 定位并单击 iFrame 中的元素

c# - .net linq with regex ismatch in where

c# - 将控制台附加到正在运行的 ASP.NET 应用程序

c# - 在 C# 中解析 jQuery 序列化数据

c# - Ef Core 3 实体类型 XOrder 不能映射到表,因为它派生自 Order Only 基本实体类型可以映射到表

entity-framework - Entity Framework : context. AddObject 不添加主人

c# - 在 Silverlight 中发出 Web 请求的问题

c# - 如何在 C# 中获得 RGB 值的同时获取颜色名称?