67

I have one project that I want to run my update-database against but I have my Models and Context in a separate project.

If I run enable-migrations I get this error: No context type was found in the assembly 'MyProject'.

This is presumably because my Context is in MyProject.MVC.

If I run enable-migrations against MyProject.MVC I have to add an app config file. I don't want to do that as I want to use the code across many projects.

So can I run enable-migrations against MyProject and somehow tell it to look in MyProject.MVC for the Context?

4

5 回答 5

108

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

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

这将MyProject使用MyProject.MVC. 您需要确保具有迁移的项目具有对具有您的上下文的项目的引用,即MyProject引用MyProject.MVC

于 2013-08-08T14:33:04.253 回答
12

您只能在包含数据库上下文类的项目中运行“启用迁移”。

您的解决方案将包含 2 个项目:

1) MyProject.Models
    |- Migrations
        |- 201401061557314_InitialCreate.cs
        |- Configuration.cs
    |- MyContext.cs
    |- App.config (no connection string)


应用程序配置

<?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 中的连接字符串来执行迁移

于 2014-01-16T16:53:25.783 回答
3

这是一种解决方法:

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

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

于 2017-02-10T16:44:48.453 回答
1

安装Microsoft.EntityFrameworkCore.Tools启用使用包管理器控制台

于 2021-08-23T03:36:01.270 回答
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. 迁移引擎需要看起来像有效连接的东西才能工作。我在代码中(在另一个项目中)创建了我的连接字符串,但这不起作用。我只是给了迁移引擎一个“有效的”连接字符串来使它工作。
  2. 将您的数据库放在迁移引擎可以找到的位置(也称为模型项目的输出文件夹),以便为迁移创建一个起点。这个起点基本上是用迁移 API 编写的数据库模式。
  3. 一旦迁移设置到位,您就可以将所有内容恢复到以前的状态,并且可以正常工作。
  4. 每次您想手动添加迁移时,都必须再次“欺骗”迁移引擎,就像第一次一样。我没有尝试过自动迁移,我想这种方法也可以。

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

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

于 2013-10-26T11:09:34.970 回答