Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 598|回复: 0

EntityFramework Core迁移时出现数据库已存在对象问题解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-28 16:21:50 | 显示全部楼层 |阅读模式

    前言

    刚开始接触EF Core时本着探索的精神去搞,搞着搞着发现出问题了,后来就一直没解决,觉得很是不爽,借着周末好好看看这块内容。

    EntityFramework Core迁移出现对象在数据库中已存在

    在EF Core之前对于迁移的命令有很多,当进行迁移出现对象已在数据库中存在时我们通过如何命令即可解决:

    Add-Migration Initial -IgnoreChanges

    但是在EF Core对于迁移现如今只存在如下两个命令:

    dotnet ef migrations add <<migration_name>>
    dotnet ef database update

    当我们第一次进行初始化迁移时,表结构完全生成通过 dotnet ef migration add initial 来初始化表,当下次再进行迁移时因为这样或者那样无意的操作导致出现如下结果

    翻译成英语则是如下的情况:

    There is already an object named in the database

    如下为第一次初始化的迁移文件,如下:

        public partial class initial : Migration
        {
            protected override void Up(MigrationBuilder migrationBuilder)
            {
                migrationBuilder.CreateTable(
                    name: "Blog",
                    columns: table => new
                    {
                        Id = table.Column<int>(nullable: false)
                            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                        Code = table.Column<string>(nullable: false),
                        Count = table.Column<int>(nullable: false),
                        Name = table.Column<string>(nullable: true),
                        Url = table.Column<string>(nullable: true)
                    },
                    constraints: table =>
                    {
                        table.PrimaryKey("PK_Blog", x => x.Id);
                    });
    
                migrationBuilder.CreateTable(
                    name: "Book",
                    columns: table => new
                    {
                        Id = table.Column<int>(nullable: false)
                            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                        Name = table.Column<string>(nullable: true)
                    },
                    constraints: table =>
                    {
                        table.PrimaryKey("PK_Book", x => x.Id);
                    });
    
                migrationBuilder.CreateTable(
                    name: "Category",
                    columns: table => new
                    {
                        Id = table.Column<int>(nullable: false)
                            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                        Name = table.Column<string>(nullable: true),
                        ProductId = table.Column<int>(nullable: false)
                    },
                    constraints: table =>
                    {
                        table.PrimaryKey("PK_Category", x => x.Id);
                    });
    
                migrationBuilder.CreateTable(
                    name: "Product",
                    columns: table => new
                    {
                        Id = table.Column<int>(nullable: false)
                            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                        Code = table.Column<string>(nullable: true),
                        Name = table.Column<string>(nullable: true)
                    },
                    constraints: table =>
                    {
                        table.PrimaryKey("PK_Product", x => x.Id);
                    });
    
                migrationBuilder.CreateTable(
                    name: "Post",
                    columns: table => new
                    {
                        Id = table.Column<int>(nullable: false)
                            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                        BlogId = table.Column<int>(nullable: false),
                        Content = table.Column<string>(nullable: true),
                        Title = table.Column<string>(nullable: true)
                    },
                    constraints: table =>
                    {
                        table.PrimaryKey("PK_Post", x => x.Id);
                        table.ForeignKey(
                            name: "FK_Post_Blog_BlogId",
                            column: x => x.BlogId,
                            principalTable: "Blog",
                            principalColumn: "Id",
                            onDelete: ReferentialAction.Cascade);
                    });
    
                migrationBuilder.CreateTable(
                    name: "ProductCategory",
                    columns: table => new
                    {
                        Id = table.Column<int>(nullable: false)
                            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                        CategoryId = table.Column<int>(nullable: false),
                        ProductId = table.Column<int>(nullable: false)
                    },
                    constraints: table =>
                    {
                        table.PrimaryKey("PK_ProductCategory", x => x.Id);
                        table.ForeignKey(
                            name: "FK_ProductCategory_Category_CategoryId",
                            column: x => x.CategoryId,
                            principalTable: "Category",
                            principalColumn: "Id",
                            onDelete: ReferentialAction.Cascade);
                        table.ForeignKey(
                            name: "FK_ProductCategory_Product_ProductId",
                            column: x => x.ProductId,
                            principalTable: "Product",
                            principalColumn: "Id",
                            onDelete: ReferentialAction.Cascade);
                    });
    
                migrationBuilder.CreateIndex(
                    name: "IX_Post_BlogId",
                    table: "Post",
                    column: "BlogId");
    
                migrationBuilder.CreateIndex(
                    name: "IX_ProductCategory_CategoryId",
                    table: "ProductCategory",
                    column: "CategoryId");
    
                migrationBuilder.CreateIndex(
                    name: "IX_ProductCategory_ProductId",
                    table: "ProductCategory",
                    column: "ProductId");
            }
    
            protected override void Down(MigrationBuilder migrationBuilder)
            {
                migrationBuilder.DropTable(
                    name: "Book");
    
                migrationBuilder.DropTable(
                    name: "Post");
    
                migrationBuilder.DropTable(
                    name: "ProductCategory");
    
                migrationBuilder.DropTable(
                    name: "Blog");
    
                migrationBuilder.DropTable(
                    name: "Category");
    
                migrationBuilder.DropTable(
                    name: "Product");
            }

    此时为了解决上述问题前提是最初的迁移类文件还在,我们需要将Up方法里面的数据全部删除而对于Down方法里面的数据可删除可不删除

        public partial class initial : Migration
        {
            protected override void Up(MigrationBuilder migrationBuilder)
            {}
    
            protected override void Down(MigrationBuilder migrationBuilder)
            {
                  ........   
            }
        }    

    通过Up方法来创建表或者修改列,通过Down方法来删除表或者修改列。上面我们创建了BlogType列,此时我们在映射时将其删除同时在Blog类中删除此字段,如下:

        public class BlogMap : EntityMappingConfiguration<Blog>
        {
            public override void Map(EntityTypeBuilder<Blog> b)
            {
                b.ToTable("Blog");
                b.HasKey(k => k.Id);
    
                b.Property(p => p.Count);
                b.Property(p => p.Url);
                b.Property(p => p.Name);
    
                b.Property(p => p.Code).IsRequired();
                //b.Property(p => p.BlogType).HasColumnType("TINYINT").IsRequired();
            }
        }

    此时我们再来进行迁移如下:

    dotnet ef migrations add removeBlogType

    此时将不会再报错且生成的removeBlogType迁移类文件如下:

        public partial class removeBlogType : Migration
        {
            protected override void Up(MigrationBuilder migrationBuilder)
            {
                migrationBuilder.DropColumn(
                    name: "BlogType",
                    table: "Blog");
            }
    
            protected override void Down(MigrationBuilder migrationBuilder)
            {
                migrationBuilder.AddColumn<byte>(
                    name: "BlogType",
                    table: "Blog",
                    type: "TINYINT",
                    nullable: false,
                    defaultValue: (byte)0);
            }
        }

    我们需要再次确保生成的迁移类文件是否是我们需要修改的字段或者对列进行修改的方法是否正确,确保无误后,接下来再来通过 dotnet ef database update 更新到数据库中

     

    如上通过意外情况导致上述错误,若是将最初迁移的整个文件夹删除了肿么办,这个时候真的没有好的办法了,我能想到的是:最好事先在建立项目时建立数据库对比文件,此时就会派上用场不用一个个类去核对表同时也利于部署时进行数据迁移。

    总结

    本文我们讲到了在EF Core迁移时可能出现的意外情况,若是删除了最初的迁移类文件也给出了能够想到的方案,不知看到此文的你有何高见?连续发表的EF Core文章都是在项目使用中遇到的问题,所以借此机会重新过了一遍,欢迎一起探讨。

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-22 19:45 , Processed in 0.061638 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表