Asp.net core中Migration工具使用的交流分享

来源:互联网 发布:wps怎么做数据透视表 编辑:程序博客网 时间:2024/06/07 00:48

一、文章参数

  • 开发工具:

    visual studio 2015 community update 3 + .net core tools(preview2) + sqlserver2012 express

  • 开发环境:

    win10(版本14393)+ .net core(版本 1.0.0-preview2-003121)

  • 项目名称:

    AirMusic

  • 项目模板:

    Asp.net core WebApi(这里不用mvc模板,是因为mvc模板初始的内容太多,这里用不到)

  • AirMusic源码地址:

    https://github.com/boomyao/Blogs

二、开篇碎语

记得去年第一次做项目,用了asp.net mvc5,因此也第一接触了EntityFramework(版本是EF6)。 现在打算用asp.net core来完成一个项目,air music是学习asp.net core时新建的demo项目,以后学习core中遇到的一些问题一般会从这个项目产生,今天这篇文章是在migration初始化数据库时发生的一些问题。

三、主要内容

1、初始化的实体模型

public class Song

    {

        public int Id { get; set; }

        [Required]

        public string SongName { get; set; }

        public virtual ICollection<ArtistSong> Artists { get; set; }

        public virtual ICollection<SongListSong> SongLists { get; set; }

    }


    //歌手

    public class Artist

    {

        public int Id { get; set; }

        [Required]

        public string Name { get; set; }

        public virtual ICollection<Album> Albums { get; set; }

        public virtual ICollection<ArtistSong> Songs { get; set; }

    }


    //song with artist n:n table

    public class ArtistSong

    {

        [Key]

        public int ArtistId { get; set; }

        [Key]

        public int SongId { get; set; }

    }



    //专辑

    public class Album

    {

        public int Id { get; set; }

        [Required]

        public string Title { get; set; }

        public virtual ICollection<Song> Songs { get; set; }

    }


    //歌单

    public class SongList

    {

        public int Id { get; set; }

        [Required]

        public string Title { get; set; }

        public string Describe { get; set; }

        public virtual ApplicationUser User { get; set; }

        public virtual ICollection<SongListSong> Songs { get; set; }

    }


    // song with songlist n:n table

    public class SongListSong

    {

        [Key]

        public int SongListId { get; set; }

        [Key]

        public int SongId { get; set; }

    }


Store Models

2、引用EFcoore相关的Nuget包

  • "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0"

    (依赖了好多ef重要组件)

  • "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"

    (引用了才可以试用migration)

  • "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0"

    (我觉得是ef连接sqlserver的必须组件)

还有就是必须在project.json里的tools节点中添加"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",不然输入命令”Add Migration“时就会报出下面这句错误。

"No parameterless constructor………“这句错误是因为ApplicationDbContext(数据库上下文类)没有写下面这个构造函数报的错误。

public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options){}

 

3、配置数据库连接

Webapi模板已经创建好了appsetting.json文件,这个文件的作用和web.config是一样的

 

4、文章包袱:Migration过程中遇到的问题

在ApplicationDbContext重写的方法OnModelCreating中,有一行代码

base.OnModelCreating(builder)

当我把这行代码注释掉时,迁移过程中就会报出如下错误:

很明显,错误发生的原因是IdentityUser没有被映射到ApplicationDbContext,所以可以知道这句代码的作用,就是用来映射Identity的几个实体类的,没有这句,数据库中就不会自动生成Users、Roles……等Table了,一个让我很困惑的问题在进行第一次Migration时出现了。AirMusic的实体中,有这样一种关系:

但是神奇的事情发生了(我不想这样的):

migrationBuilder.CreateTable(

                name: "ArtistSongs",

                columns: table => new

                {

                    ArtistId = table.Column<int>(nullable: false),

                    SongId = table.Column<int>(nullable: false),

                    //ArtistId1 = table.Column<int>(nullable: true)

                },

                constraints: table =>

                {

                    table.PrimaryKey("PK_ArtistSongs", x => new { x.ArtistId, x.SongId });

                    table.ForeignKey(

                        name: "FK_ArtistSongs_Artists_ArtistId",

                        column: x => x.ArtistId,

                        principalTable: "Artists",

                        principalColumn: "Id",

                        onDelete: ReferentialAction.Cascade);

                    //table.ForeignKey(

                    //    name: "FK_ArtistSongs_Artists_ArtistId1",

                    //    column: x => x.ArtistId1,

                    //    principalTable: "Artists",

                    //    principalColumn: "Id",

                    //    onDelete: ReferentialAction.Restrict);

                    table.ForeignKey(

                        name: "FK_ArtistSongs_Songs_SongId",

                        column: x => x.SongId,

                        principalTable: "Songs",

                        principalColumn: "Id",

                        onDelete: ReferentialAction.Cascade);

                });


            migrationBuilder.CreateTable(

                name: "SongListSongs",

                columns: table => new

                {

                    SongListId = table.Column<int>(nullable: false),

                    SongId = table.Column<int>(nullable: false),

                    //SongListId1 = table.Column<int>(nullable: true)

                },

                constraints: table =>

                {

                    table.PrimaryKey("PK_SongListSongs", x => new { x.SongListId, x.SongId });

                    table.ForeignKey(

                        name: "FK_SongListSongs_Songs_SongId",

                        column: x => x.SongId,

                        principalTable: "Songs",

                        principalColumn: "Id",

                        onDelete: ReferentialAction.Cascade);

                    table.ForeignKey(

                        name: "FK_SongListSongs_SongLists_SongListId",

                        column: x => x.SongListId,

                        principalTable: "SongLists",

                        principalColumn: "Id",

                        onDelete: ReferentialAction.Cascade);

                    //table.ForeignKey(

                    //    name: "FK_SongListSongs_SongLists_SongListId1",

                    //    column: x => x.SongListId1,

                    //    principalTable: "SongLists",

                    //    principalColumn: "Id",

                    //    onDelete: ReferentialAction.Restrict);

                });


初次Migration中发生意外的代码(注释的那些)

自动添加了带artist1songlist1的字段,我很希望知道的朋友告诉我解决的办法!!我实在不知道怎么让EF不自动添加这个多余的字段,所以我把那些多余的字段都注释掉后,才update-database到数据库:

song-artist[N:N] , song-songlist[N:N]

在ApplicationDbContext的OnModelCreating方法里,可以手动的配置数据库中的关系,像什么组合主键啦,组合外键啦等等各种约束,都可以 实现。特别是数据库中实体的关系配置(1:1,1:N,N:N),例如:用方法builder.HasOne().WithMany()就可以建立[1:N]的关系。AirMusic初次Migration中,我也手动的配置了一些关系:

var entityAS=builder.Entity<ArtistSong>();

            entityAS.HasKey("ArtistId", "SongId");

            entityAS.HasOne<Artist>()

                .WithMany()

                .HasForeignKey("ArtistId");


            var entitySS = builder.Entity<SongListSong>();

            entitySS.HasKey("SongListId", "SongId");

            entitySS.HasOne<SongList>()

                .WithMany()

                .HasForeignKey("SongListId");

上面代码的作用是,ArtistId和SongId设为ArtistSong的组合主键,ArtistSong的ArtistId设为Artist的外键。entitySS的作用也大致相同。

四、篇后总结

第一次完整的写一篇博文,晚上去吃饭是电脑自动重启更新了,vscode里的代码都没保存,打开博客园文章管理发现什么都没了,难过的就去听歌睡觉了。第二天起来打算从新来过时,发现有一行“自动保存恢复”,那个感觉就和中了100块的彩票一样。

希望有人看完这篇文章吧,新写手最需要的就是多给建议呀!谢谢

原文地址:http://www.cnblogs.com/boomyao/p/5745525.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

阅读全文
0 0
原创粉丝点击