Entity framework 4 为什么实体框架';s EF迁移添加迁移步骤是否需要数据库连接字符串?

Entity framework 4 为什么实体框架';s EF迁移添加迁移步骤是否需要数据库连接字符串?,entity-framework-4,entity-framework-4.3,entity-framework-migrations,Entity Framework 4,Entity Framework 4.3,Entity Framework Migrations,我试图使用和理解EF迁移(使用EF 4.3.1,代码优先)。为了构建新的更改,我必须使用如下命令: Add-Migration MyMigration -ConnectionString "Data Source=.;Initial Catalog=mydb;" -ConnectionProviderName "System.Data.SqlClient" -StartUpProjectName MyWebsite -ProjectName MyEF.Migratio

我试图使用和理解EF迁移(使用EF 4.3.1,代码优先)。为了构建新的更改,我必须使用如下命令:

Add-Migration MyMigration
   -ConnectionString "Data Source=.;Initial Catalog=mydb;" 
   -ConnectionProviderName "System.Data.SqlClient"
   -StartUpProjectName MyWebsite 
   -ProjectName MyEF.Migrations
为什么添加迁移需要连接字符串数据<代码>更新数据库需要一个,这很有意义。但是,添加迁移不具备DbContext和配置所需的一切吗

这不仅仅是一个无聊的奇迹,给它一个数据库是非常令人困惑的,因为我们有一个“多租户”的东西,其中所需的数据库是灵活的,可以在不同的请求之间更改,更不用说在静态编译时了。因此,如果
addmigration
实际上正在使用该数据库进行任何操作,那么我们就有问题了


更新:我们放弃了EF迁移,改用EF迁移,我们很高兴。它的速度要快得多,甚至要计算我们必须编写两次(一次用于EF对象,一次用于迁移)的事实,而且它没有本问题中讨论的问题。

阅读您的问题时,我很好奇,所以我启动了Sql Server探查器,查看在运行添加迁移时发生了什么。它确实连接到数据库并访问数据库以检查
\uu MigrationHistory

尝试创建第二个基于代码的迁移而不运行第一个迁移时产生的错误消息也显示了这一点:

由于以下原因,无法生成显式迁移 显式迁移挂起:[201205291928386_-foo]。应用 在尝试生成新文件之前挂起显式迁移 显式迁移

我认为迁移引擎使用数据库中的序列化模型来计算新迁移中应该包括哪些迁移步骤

据我所知,数据库仅用作代码生成的助手。只要您使用的所有不同的数据库都与代码中的模型兼容,这对您的用户来说就不会是问题

编辑 正如@Ladislav Mrnka指出的,如果混合使用基于代码的迁移和自动迁移,则需要检查数据库。构建新迁移时,它应该包括自上次迁移以来模型中发生的任何更改。如果您使用的是自动迁移,那么代码中不会跟踪这些迁移。计算迁移中要包含的更改时,最后一次运行的迁移将用作基础。检查这一点的唯一方法是数据库,因为可能会打开自动迁移


如果您只运行基于代码的迁移(我认为这是保持控制的唯一选项),那么该数据库可以被视为代码生成帮助。只要您连接到的所有数据库中都确保了模型兼容性,一切都应该正常。

Add Migration
检查数据库是否存在,并与
\u MigrationHistory
表交互。正如@Anders Abel所提到的,它用于调查挂起的迁移,也用于选择以前的模型以实际查找已更改的内容-如果您将显式迁移添加到启用自动迁移的解决方案中,这一点尤其重要。

OP写道:

但是,添加迁移并不能从DbContext中获得所需的一切 配置呢

否-正如其他人在这里提到的,手动迁移代码的设计器部分(由
add Migration
创建)包含数据库架构的快照

也就是说,使用连接字符串等的事实非常奇怪。EF通常从DbContext类和Web.Config中暗示它。在一个只有一个数据库和一个DbContext的项目中,我创建了一个配置类,并添加了一个手动迁移:

add-migration
我不必传递任何其他命令行参数。这是在EF4.3.1中-可能您使用的是CTP或一些旧版本,或者只是误解了文档

如果我有多个DBs或DBContext,那么我有多个配置类,并使用例如:

add-migration -conf Log
它使用Web.config中的配置类和相关连接字符串为该数据库/DbContext添加手动迁移

下面是用于存储日志(与主数据库分开)的简单DbContext的较长代码示例:


在Package Manager控制台中。

我观看了2014年3月Rowan Miller的视频:

在视频中,Rowan解释说,
addmigration
命令执行多个步骤,其中包括名为
edmmodeldifference
的组件。 EDMModelDifference将当前模型与上次迁移的上一个模型(嵌入上次迁移的resx文件中)进行比较,然后计算对数据库所需的更改

因此,
edmmodeldifference
组件需要数据库连接

视频中描述的步骤包括:

  • 从代码构建当前模型
  • 从上次迁移中获取上一个模型(作为快照存储在resx文件中)
  • 计算所需的数据库更改(由
    EDMModelDifference
    完成)
  • 生成了新的迁移文件
  • 从理论上讲,我们可以假定,将当前模型与上次迁移的模型进行比较就足以生成新的迁移。 但与此同时,其他人也可以对数据库进行更改。这可能就是为什么还要对数据库进行检查的原因。 如果不这样做,生成的迁移文件就不需要是正确的



    再看一看第二个名为

    的视频,如果我将AutomaticMigrationsEnabled设置为false,该分析将如何更改?(我认为如果我不再需要指定数据库,我可以生活在一个自动迁移的自由世界中。)不幸的是,我认为分析不会改变。他们无法让EF知道你是否总是
    namespace MyProj.Models.Log
    {
        public class LogDb : DbContext
        {
            public DbSet<LogLine> LogLines { get; set; }
            public DbSet<LogTag> LogTags { get; set; }
    
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            }
        }
    
        public LogDb()
    #if DEPLOYDB
             : base("LogDeploy")
    #else
             : base()
    #endif
         {
         }
    }
    
    namespace MyProj.Migrations
    {
        internal sealed class Log : DbMigrationsConfiguration<LogDb>
        {
            public Log()
            {
                AutomaticMigrationsEnabled = true;
            }
        }
    }
    
    <add name="LogDb" connectionString="Initial Catalog=Log;Data Source=.\SqlExpress;Integrated Security=SSPI;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" />
    <add name="LogDeploy" connectionString="Initial Catalog=Log;Data Source=00.00.000.00,12345;User ID=sql;Password=xxx;Network Library=DBMSSOCN" providerName="System.Data.SqlClient" />
    
    > update-database -conf Log