是否在单独的程序集中启用上下文迁移?


67

我有一个要运行的项目,update-database但我的模型和上下文位于单独的项目中。

如果我运行enable-migrations,则会出现此错误:在程序集“ MyProject”中未找到任何上下文类型。

大概是因为我的上下文在MyProject.MVC中。

如果我enable-migrations针对MyProject.MVC运行,则必须添加一个应用程序配置文件。我不想这样做,因为我想在许多项目中使用代码。

所以我可以enable-migrations针对MyProject运行,并以某种方式告诉它在MyProject.MVC中查找上下文吗?


PM> enable-migrations -projectname yourproject
Frank Myat Thu

Answers:


107

这仅在EF 6中有效,但是有一个发行版-ContextProjectName参数添加到了-enable-migrations命令中。通过使用此命令,您可以执行以下操作:

enable-migrations -ContextProjectName MyProject.MVC -StartUpProjectName MyProject.MVC 
-ContextTypeName MyProject.MVC.MyContextFolder.MyContextName -ProjectName MyProject

这将MyProject使用中的上下文向您的项目添加迁移MyProject.MVC。您需要确保包含Migrations的项目对具有Context的项目具有MyProject引用,即引用MyProject.MVC


7
这是正确的方法,我很惊讶@Jon尚未接受此答案。
JARRRRG 2014年

这为我做了工作。感谢@SOfanatic
Alaor

1
如果MyProject具有的上下文MyProject.MVC,那不会创建循环依赖吗?
Arithmomaniac

@ArithmomaniacMyProject引用MyProject.MVC,.MVC项目没有对该项目的引用。
SOfanatic

DbContext由BusinessLogicLayer继承,然后又继承到WebProject的场景如何处理,那么将导致循环引用
Ajay Suwalka

12

您只能在包含Database Context类的项目中运行“ 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”文件夹

紧随其后的是“ Update-Database”->迁移将使用启动项目中Web.config中的连接字符串来执行迁移


3

这是一种解决方法:

将一个类添加到MyProject(用于迁移的项目)中。使此类继承dbcontext(MyProject.MVC中的那个)。

然后在MyProject上运行EF迁移命令。


0

我遇到了同样的问题,并且正在使用EntityFramework 4.3.1。似乎EF6解决了这个问题(根据@SOfanatic的回答),但是由于某些重大更改(例如,在DataAnnotations中),我不想升级到EF6。

因此,我为解决此问题所做的工作(以及在此过程中学到的知识):

  1. 创建一个新的解决方案(空项目),并将该项目添加到要为其启用迁移的模型所在的位置(在您的情况下为MyProject.MVC)。在添加现有项目之前,可能需要为其安装必需的NuGet软件包。

  2. 添加带有连接字符串的配置文件(不用担心,这只是在欺骗迁移引擎)。将现有数据库复制到模型项目输出文件夹(在您的情况下,应为MVC \ bin \ Debug)。确保配置文件中的连接字符串指向该数据库:

    <connectionStrings>
        <add name="MyDB" providerName="System.Data.SqlServerCe.4.0" connectionString="DataSource=|DataDirectory|\MyDB.sdf"/>
      </connectionStrings>
    
  3. 由于您使用的是新解决方案,因此请将模型项目设置为启动项目(可以删除默认项目)。

  4. 在程序包管理器控制台中运行enable-migrations命令。它应该使用两个文件创建一个Migrations文件夹:Configuration.cs和带有时间戳的InitialCreate.cs文件。拥有InitialCreate很好,这就是为什么将现有数据库放在模型项目的输出文件夹中的原因(但这是可选的)。

  5. 重新加载原始解决方案,以便更新这些更改。

据我了解(据我了解):

  1. 迁移引擎需要看起来像有效连接的东西才能正常工作。我正在用代码创建连接字符串(在另一个项目中),但是没有用。我只是给了Migrations引擎一个“有效”的连接字符串以使其正常工作。
  2. 将您的数据库放置在迁移引擎可以找到它的位置(aka模型项目的输出文件夹),以便为迁移创建起点。基本上,此起点是使用Migrations API编写的数据库架构。
  3. 迁移到位后,您可以将所有内容恢复到以前的状态,并且一切正常。
  4. 每次您要手动添加迁移时,都必须像第一次那样再次“欺骗”迁移引擎。我还没有尝试过自动迁移,因为我猜想这种方法也可以。

顺便说一句,我使用的是SQL Server CE 4.0数据库,因此与标准SQL Server DB或LocalDB相比,有关连接字符串的某些信息有所不同。除此之外,一切都一样。

希望这对您有所帮助,并为您提供一些见识。如果您了解有关此迁移工作方式的更多信息,请发表评论。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.