在单独的程序集中启用带有上下文的迁移?
Posted
技术标签:
【中文标题】在单独的程序集中启用带有上下文的迁移?【英文标题】:Enable Migrations with Context in Separate Assembly? 【发布时间】:2013-08-10 04:57:14 【问题描述】:我想针对一个项目运行 update-database
,但我的模型和上下文位于单独的项目中。
如果我运行 enable-migrations
我会收到以下错误:
在程序集“MyProject”中找不到上下文类型。
这大概是因为我的 Context 在 MyProject.MVC 中。
如果我针对 MyProject.MVC 运行 enable-migrations
,我必须添加一个应用配置文件。我不想这样做,因为我想在许多项目中使用代码。
那么我可以对 MyProject 运行 enable-migrations
并以某种方式告诉它在 MyProject.MVC 中查找上下文吗?
【问题讨论】:
PM> enable-migrations -projectname yourproject 【参考方案1】:安装 Microsoft.EntityFrameworkCore.Tools 以启用使用包管理器控制台
【讨论】:
【参考方案2】:这是一个解决方法:
在 MyProject(迁移项目)中添加一个类。让这个类继承dbcontext(MyProject.MVC中的那个)。
然后在 MyProject 上运行 EF 迁移命令。
【讨论】:
【参考方案3】:您只能在包含数据库上下文类的项目中运行“Enable-Migrations”。
您的解决方案将包含 2 个项目:
1) MyProject.Models
|- Migrations
|- 201401061557314_InitialCreate.cs
|- Configuration.cs
|- MyContext.cs
|- App.config (no connection string)
App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
2) MyProject.MVC
|- Filters
|- InitializeSimpleMembershipAttribute.cs
InitializeSimpleMembershipAttribute.cs
namespace MyProject.MVC.Filters
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
private static SimpleMembershipInitializer _initializer;
private static object _initializerLock = new object();
private static bool _isInitialized;
public override void OnActionExecuting(ActionExecutingContext filterContext)
// Ensure ASP.NET Simple Membership is initialized only once per app start
LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
private class SimpleMembershipInitializer
public SimpleMembershipInitializer()
try
Database.SetInitializer<MyContext>(new MigrateDatabaseToLatestVersion<MyContext, MyProject.Model.Migrations.Configuration>());
using (var context = new MyContext())
context.Database.Initialize(force: true);
if (!context.Database.Exists())
// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
catch (Exception ex)
throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
将 MyProject.MVC 设置为启动项目
在包管理器中,选择项目:MyProject.Models
然后运行“Enable-Migrations”在 MyProject.Models 中创建“Migrations”文件夹
后跟“更新数据库” -> 迁移将使用启动项目中 Web.config 中的连接字符串来执行迁移
【讨论】:
【参考方案4】:我遇到了同样的问题,我使用的是 EntityFramework 4.3.1。似乎 EF6 解决了这个问题(根据@SOfanatic 的回答),但由于一些重大更改(例如在 DataAnnotations 中),我不想升级到 EF6。
那么,我做了什么来解决这个问题(以及我在这个过程中学到了什么):
创建一个新的解决方案(空项目)并将项目添加到您想要为其启用迁移的模型(在您的情况下为 MyProject.MVC)。在添加现有项目之前,您可能需要为其安装所需的 NuGet 包。
添加一个带有连接字符串的配置文件(别担心,这只是为了欺骗迁移引擎)。将现有数据库复制到模型项目输出文件夹(在您的情况下应该是 MVC\bin\Debug)。确保配置文件中的连接字符串指向该数据库:
<connectionStrings> <add name="MyDB" providerName="System.Data.SqlServerCe.4.0" connectionString="DataSource=|DataDirectory|\MyDB.sdf"/> </connectionStrings>
由于您在新的解决方案中,请将您的模型项目设置为启动项目(您可以删除默认项目)。
在包管理器控制台中运行 enable-migrations 命令。它应该创建一个包含两个文件的 Migrations 文件夹:一个 Configuration.cs 和一个带时间戳的 InitialCreate.cs 文件。很高兴拥有 InitialCreate,这就是为什么您将现有数据库放在模型项目的输出文件夹中(但这是可选的)。
重新加载您的原始解决方案,以便更新这些更改。
我学到了什么(据我所知):
-
迁移引擎需要看起来像有效连接的东西才能工作。我在代码中(在另一个项目中)创建了我的连接字符串,但这不起作用。我只是给了 Migrations 引擎一个“有效的”连接字符串来让它工作。
将您的数据库放在迁移引擎可以找到的位置(也称为模型项目的输出文件夹),以便为迁移创建一个起点。这个起点基本上是用迁移 API 编写的数据库架构。
迁移设置到位后,您可以将所有内容恢复到之前的状态,并且一切正常。
每次您想要手动添加迁移时,都必须再次“欺骗”迁移引擎,就像第一次一样。我没有尝试过自动迁移,我想这种方法也可以。
顺便说一下,我使用的是 SQL Server CE 4.0 数据库,因此与标准 SQL Server DB 或 LocalDB 相比,连接字符串的某些内容有些不同。除此之外,一切都一样。
希望这对您有所帮助并为您提供一些见解。如果您了解有关此迁移工作方式的更多信息,请发表评论。
【讨论】:
【参考方案5】:这仅适用于 EF 6,但有一个 release 将 -ContextProjectName
参数添加到 -enable-migrations
命令。通过使用此命令,您可以执行以下操作:
enable-migrations -ContextProjectName MyProject.MVC -StartUpProjectName MyProject.MVC
-ContextTypeName MyProject.MVC.MyContextFolder.MyContextName -ProjectName MyProject
这将使用MyProject.MVC
中的上下文将迁移添加到您的MyProject
项目。
您需要确保具有 Migrations 的项目具有对具有您的 Context 的项目的引用,即 MyProject
引用 MyProject.MVC
【讨论】:
如果MyProject
有MyProject.MVC
的上下文,那不会产生循环依赖吗?
@Arithmomaniac MyProject
引用 MyProject.MVC
,.MVC 项目没有对该项目的引用。
DbContext被BusinessLogicLayer继承再继承到WebProject的场景,会导致循环引用
enable-migrations
现在已过时。是否有另一种方法可以为 .Net Core 配置它?
@Varin .. 在 EF Core 中有点不同,请查看此链接 docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/…以上是关于在单独的程序集中启用带有上下文的迁移?的主要内容,如果未能解决你的问题,请参考以下文章
实体框架 enable-migrations 在程序集中找不到上下文类型
Code-First,当我进行启用迁移时,我得到“在程序集'DOC'中找不到上下文类型”