EntityFramework项目“The model backing xxx context has changed ”错误解决-CodeFirst迁移踩坑记录

本文为本人日记,用于个人记录。

报错现象:

The model backing the 'XXXXContext' context has changed since the database was created. Consider using Code First Migrations to update the database 

 

环境及背景:

接收古董项目10年前的代码,摊上传说中的祖传代码,踩坑无数,今天说说其中一个坑。个人是不喜欢EF的,做个Demo还行,真实项目上使用灵活性太差。

古董代码环境:VS2010+EF4.1+WCF+C#+SQLServer2008+WinForm+C++_硬件API+硬件

需求:数据库不能重建,在老库(已有数据)某两个数据表增加几个字段。(注意需求是已有数据)

工程组成:Model层、WCFService层、WinFormClient层

 

踩坑场景还原:

针对想当然做法:Model层对表对应实体中增加字段、数据库中手动以SQL增加两个列、更新WCF引用,坐等测试通过

运行现象:WinFormClient调用WCF,在WCFService层非改动表使用using (XXDBContext db = new XXDBContext())抛出异常,异常消息:The model backing the 'XXXXContext' context has changed since the database was created. Consider using Code First Migrations to update the database 

不好,大事不妙,悟空坏了蟠桃大会,后果很严重,黎叔很生气。上下求索的路子曲折,这里不赘述了。

 

前提:重要的事情说三遍,备份数据库备份源码X3

 

解决办法:

关键思想:CodeFirst模式EF代码与数据库形成了绑定关系,手动修改数据库增加列后,EF不认。通过EF CodeFirst迁移方式,让EF对数据表字段新增修改。

 

步骤

  1. Vs2010无法联网,通过浏览器到nuget官网https://www.nuget.org下载entityframework.4.3.1的nuget包【entityframework.4.3.1.nupkg】,准备离线安装。(注意,不要下载EntityFramework 4.1.10331包,因为老版本EF不支持“Enable-migrations”命令,会报【无法将“Enable-migrations”识别为cmdlet】)
  2. vs2010中查看或设置程序包源,本例,将entityframework.4.3.1.nupkg拷贝到C:\Users\Administrator\AppData\Roaming\NuGet\Cache
  3. 程序包源选择local,默认项目选择实体类工程, vs2010程序包管理控制台输入命令: Install-Package EntityFramework -Version 4.3.1
  4. vs2010程序包管理控制台输入命令:Enable-Migrations
  5. 提示错误,根据错误得知此命令想要访问数据库。
  6. 在实体类工程中增加app.config添加数据库连接字符串,如下
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <configSections>
        
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
      <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
          <parameters>
            <parameter value="Data Source=XX;Initial Catalog=XX;user id=XXX;password=XXX" />
        </parameters>
        </defaultConnectionFactory>
      </entityFramework>
    </configuration>

     

  7. 程序包管理控制台再次输入启用迁移的命令Enable-Migrations,本例前面尝试过几次所以使用Enable-Migrations -Force

  8. PM> Enable-Migrations
    Migrations have already been enabled in project 'EntityModel'. To overwrite the existing migrations configuration, use the -Force parameter.
    PM> Enable-Migrations -Force
    Code First Migrations enabled for project EntityModel.
    

     

  9. 把实体类工程EntityModel设置为启动项目

  10. 再次执行命令Add-Migration AddCol_Table。如果仍报数据库连接错误,则可尝试使用“

    Add-Migration AddCol_Table -ConnectionString "Data Source=127.0.0.1;Initial Catalog=xxx;user id=xx;password=xx"

    位于命令管道位置 1 的 cmdlet Add-Migration

    请为以下参数提供值:

    ConnectionProviderName: System.Data.SqlClient

    Scaffolding migration 'AddCol_C_RoutinePower'.

  11.  

    此命令执行后会在当前工程下创建一个202008280232342_AddCol_Table.cs文件,文件代码大致类似如下
    namespace EntityModel.Migrations
    {
        using System.Data.Entity.Migrations;
        
        public partial class AddCol_Table: DbMigration
        {
            public override void Up()
            {
                
                CreateTable(
                    "xxx",
                    c => new
                        {
                            xxxx
                        })
                    .PrimaryKey(t => t.xxx);
                
            }
            
            public override void Down()
            {
                DropIndex("xxx", new[] { "cc" });
                DropForeignKey("xxx", "bb", "aa");
                DropTable("xxx");
            }
        }
    }
    

     

  12. 我们不需要上面的删除表和新增表代码,修改代码为新增字段删除字段

    namespace EntityModel.Migrations
    {
        using System.Data.Entity.Migrations;
        
        public partial class AddCol_C_PowerCalibrateBase : DbMigration
        {
            public override void Up()
            {
                //下面的代码是wdh手动添加的。
                AddColumn("dbo.xxx", "aaa", c => c.Double(nullable: null));
            }
    
            public override void Down()
            {
                DropColumn("dbo.xxx", "aaa");
            }
        }
    }
    

     

  13. 输入命令,用指定连接字符串将上述代码更新到数据库。命令:update-database -verbose -ConnectionString "Data Source=127.0.0.1;Initial Catalog=xxxx;user id=xxx;password=xxx",在提示后输入“System.Data.SqlClient”

  14. PM> update-database -verbose -ConnectionString "Data Source=127.0.0.1;Initial Catalog=xxxx;user id=xxx;password=xxx"
    位于命令管道位置 1 的 cmdlet Update-Database
    请为以下参数提供值:
    ConnectionProviderName: System.Data.SqlClient
    Using NuGet project 'EntityModel'.
    Using StartUp project 'EntityModel'.
    Target database is: 'xxx' (DataSource: 127.0.0.1, Provider: System.Data.SqlClient, Origin: Explicit).
    Applying explicit migrations: [202008280232342_AddCol_Table].
    Applying explicit migration: 202008280232342_AddCol_xxx.
    ALTER TABLE [dbo].[xxx] ADD [xxx] [float]
    ALTER TABLE [dbo].[xxx] ADD [xxx] [float]
    CREATE TABLE [__MigrationHistory] (
        [MigrationId] [nvarchar](255) NOT NULL,
        [CreatedOn] [datetime] NOT NULL,
        [Model] [varbinary](max) NOT NULL,
        [ProductVersion] [nvarchar](32) NOT NULL,
        CONSTRAINT [PK___MigrationHistory] PRIMARY KEY ([MigrationId])
    )
    BEGIN TRY
        EXEC sp_MS_marksystemobject '__MigrationHistory'
    END TRY
    BEGIN CATCH
    END CATCH
    [Inserting migration history record]
    PM> 
    

     

  15. 检查数据库中表字段是否已经新增成功了。

  16. 如果update-database命令执行未报错,前面已执行过多次,但数据库中对应的表字段未加上。处理办法:将[dbo].[__MigrationHistory]表中的与当前记录重复202008280307106_AddCol_Table记录删除,然后重新执行一遍update-database命令。

  17. 打开客户端,重新调用WCF,OK,通过。

 

官方参考

https://docs.microsoft.com/zh-cn/ef/ef6/modeling/code-first/migrations/?redirectedfrom=MSDN

参考:
https://www.cnblogs.com/chenwolong/p/migrations.html

https://www.cnblogs.com/haogj/archive/2012/02/17/2356537.html

https://www.cnblogs.com/Laimic/articles/4318707.html

https://blog.csdn.net/hit_why/article/details/72778785?utm_source=blogxgwz28

nuget包:

https://www.nuget.org/packages/EntityFramework/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值