• EF6学习笔记(六) 创建复杂的数据模型


    EF6学习笔记总目录:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理)

    本篇原文地址:Creating a More Complex Data Model

    本篇讲的比较碎,很多内容本人认为并不是EF的内容,既然原文讲了,那就按照原文来学习吧。。。

    第1步:通过属性来定制化数据模型

    通过 DataType Attribute来定义数据模型字段属性:

    先加申明 using System.ComponentModel.DataAnnotations;

    然后为需要定义属性的字段加上属性:(例如EnrollmentDate 加上日期DataType,以及显示格式的属性)

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace EFTest.Models
    {
        public class Student
        {
            public int ID { get; set; }
            public string LastName { get; set; }
            public string FirstMidName { get; set; }
            [DataType(DataType.Date)]
            [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
            public DateTime EnrollmentDate { get; set; }
    
            public virtual ICollection<Enrollment> Enrollments { get; set; }
        }
    }

    DataType 枚举可以通过 DataType Enumeration链接来查看;主要有用的是:Date,Time,EmailAddress,Password等;
    通过DataType定义的数据属性,在应用中得到特殊的数据处理功能,比如Email的话,就在显示的时候自动变为点击发Email的Link;如果Date的话,会在前端自动显示为一个日期输入选择框(在HTML5的情况下);

    但是DataType不提供验证功能,并且也不特别指定显示格式,默认的显示格式基于服务器的CultureInfo

    DispalyFormat属性定义就是用来明确定义显示格式;

    DisplayFormat可以单独使用,但建议是配合DataType一起使用,配合使用会有以下优点:

    1、HTML5支持的浏览器可以根据DataType做出一些特定的调整及显示(比如会显示计算器、日期输入框、Email地址链接等等)

    2、默认情况下,浏览器会根据客户端计算机的本地化显示设置来进行渲染(比如本地化的日期时间格式)

    3、DataType属性可以让MVC选择正确的字段类型去渲染数据,DisplayFormat使用字符串类型模板;

    更多的信息可以参考:MVC 5 Introduction: Examining the Edit Methods and Edit View

    通过StringLength 属性定义长度

    可以通过StringLength这个属性来定义一个字段的最长长度,并且可以设置出现错误后应该提供的错误信息;

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace EFTest.Models
    {
        public class Student
        {
            public int ID { get; set; }
            [StringLength(50)]
            public string LastName { get; set; }
            [StringLength(50, ErrorMessage = "First name 不可以超过50个字符.")]
            public string FirstMidName { get; set; }
            [DataType(DataType.Date)]
            [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
            public DateTime EnrollmentDate { get; set; }
    
            public virtual ICollection<Enrollment> Enrollments { get; set; }
        }
    }

    比如设定LastName、FirstMidName最长只能50个字符,并且在FirstMidName输入超过50个字符的时候提示相应错误;
    另外,StringLength属性定义不能防止用户输入空格,所以可以通过RegularExpression来进行限制:

    [RegularExpression(@"^[A-Z]+[a-zA-Z''-'s]*$")]

    以上这个属性定义,限制首字母为大写,后面也必须为字母;

    PS: MaxLength属性定义也能定义字段最大长度,但是并不提供客户端验证。

    这个时候如果直接运行应用,并点击Students页面,就会有以下错误:

    说明数据模型变了,数据库也需要先升级才可以;

    先在PM控制台执行 add-migration MaxLengthOnNames

    会自动创建一个带时间戳的数据升级文件;然后在PM控制台继续输入:update-database

    完成后,就可以再次尝试进入应用的Student页面,并点击Create进入新建页面:

    Column 属性定义:当一些特定情况下,希望数据库里的字段名采用一个约定格式名,而模型中是另一个名称,则需要通过Column来强制换个名字:

    首先,添加申明:using System.ComponentModel.DataAnnotations.Schema;

    然后用[Column("NewColumnName")] 定义数据库中的列名:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace EFTest.Models
    {
        public class Student
        {
            public int ID { get; set; }
            [StringLength(50)]
            public string LastName { get; set; }
            [StringLength(50, ErrorMessage = "First name 不可以超过50个字符.")]
            [Column("FirstName")]
            public string FirstMidName { get; set; }
            [DataType(DataType.Date)]
            [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
            public DateTime EnrollmentDate { get; set; }
    
            public virtual ICollection<Enrollment> Enrollments { get; set; }
        }
    }

    当然,在做了这个改动后,需要今天数据库升级操作:

    在PM控制台输入以下命令:
      add-migration ColumnFirstName
      update-database

    更新后,列名变了,并且DataType从nvarchar(MAX) 变为 nvarchar(50):

    PS: 这个操作可以通过 Fluent API 来完成,后面也会提及到。

    将Student模型变更为以下完整版本:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace EFTest.Models
    {
        public class Student
        {
            public int ID { get; set; }
            [Required]
            [StringLength(50)]
            [Display(Name = "Last Name")]
            public string LastName { get; set; }
            [Required]
            [StringLength(50, ErrorMessage = "First name 不可超过50个字符.")]
            [Column("FirstName")]
            [Display(Name = "First Name")]
            public string FirstMidName { get; set; }
            [DataType(DataType.Date)]
            [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
            [Display(Name = "Enrollment Date")]
            public DateTime EnrollmentDate { get; set; }
    
            [Display(Name = "Full Name")]
            public string FullName
            {
                get
                {
                    return LastName + ", " + FirstMidName;
                }
            }
    
            public virtual ICollection<Enrollment> Enrollments { get; set; }
        }
    
    }

    [Required]对于值类型的是不需要的,例如int , DateTime, double, float ,因为这些值本身是不可以为空NULL的;

    对于字符串类型的属性(property),可以通过设置最小长度来代替[Required]:

    [Display(Name = "Last Name")]
    [StringLength(50, MinimumLength=1)]
    public string LastName { get; set; }

    Display定义在显示View的时候,对应该属性(property)的输入框标题内容;

    另外,FullName是一个计算出来的属性(property),所以只有get ,没有set ,这样在数据库里是不会增加 FullName这个列的;

    新建Instructor模型:(和Student 模型差不多)

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace EFTest.Models
    {
        public class Instructor
        {
            public int ID { get; set; }
    
            [Required]
            [Display(Name = "Last Name")]
            [StringLength(50)]
            public string LastName { get; set; }
    
            [Required]
            [Column("FirstName")]
            [Display(Name = "First Name")]
            [StringLength(50)]
            public string FirstMidName { get; set; }
    
            [DataType(DataType.Date)]
            [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
            [Display(Name = "Hire Date")]
            public DateTime HireDate { get; set; }
    
            [Display(Name = "Full Name")]
            public string FullName
            {
                get { return LastName + ", " + FirstMidName; }
            }
    
            public virtual ICollection<Course> Courses { get; set; }
            public virtual OfficeAssignment OfficeAssignment { get; set; }
        }
    
    }

    当然也可以简化属性定义为一行:(通过逗号来分割)

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace EFTest.Models
    {
        public class Instructor
        {
            public int ID { get; set; }
    
            [Display(Name = "Last Name"), StringLength(50, MinimumLength = 1)]
            public string LastName { get; set; }
    
            [Column("FirstName"), Display(Name = "First Name"), StringLength(50, MinimumLength = 1)]
            public string FirstMidName { get; set; }
    
            [DataType(DataType.Date), Display(Name = "Hire Date"), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
            public DateTime HireDate { get; set; }
    
            [Display(Name = "Full Name")]
            public string FullName
            {
                get { return LastName + ", " + FirstMidName; }
            }
    
            public virtual ICollection<Course> Courses { get; set; }
            public virtual OfficeAssignment OfficeAssignment { get; set; }
    
        }
    
    }

    在Instructor模型中 Courses 和 OfficeAssignment为导航属性,采用virtual来定义为延迟加载;
    Instructor对应Courses 是1对n ,所以采用ICollection<T>来表示;

    Instructor对应OfficeAssignment是1对1,所以直接采用OfficeAssignment来定义;

    新建OfficeAssignment模型:

    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace EFTest.Models
    {
        public class OfficeAssignment
        {
            [Key]
            [ForeignKey("Instructor")]
            public int InstructorID { get; set; }
            [StringLength(50)]
            [Display(Name = "Office Location")]
            public string Location { get; set; }
    
            public virtual Instructor Instructor { get; set; }
        }
    
    }

    Instructor对应OfficeAssignment是1对1或者 1对0,即OfficeAssignment表中的InstructorID一定是在Instructor存在这个ID的;

    所以对于OfficeAssignment InstructorID需要设置为主键,并且要定义为从Instructor ID来的外键;

    修改Course模型

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace EFTest.Models
    {
        public class Course
        {
            [DatabaseGenerated(DatabaseGeneratedOption.None)]
            [Display(Name = "Number")]
            public int CourseID { get; set; }
    
            [StringLength(50, MinimumLength = 3)]
            public string Title { get; set; }
    
            [Range(0, 5)]
            public int Credits { get; set; }
    
            public int DepartmentID { get; set; }
    
            public virtual Department Department { get; set; }
            public virtual ICollection<Enrollment> Enrollments { get; set; }
            public virtual ICollection<Instructor> Instructors { get; set; }
        }
    
    }

    新建Department模型

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace EFTest.Models
    {
        public class Department
        {
            public int DepartmentID { get; set; }
    
            [StringLength(50, MinimumLength = 3)]
            public string Name { get; set; }
    
            [DataType(DataType.Currency)]
            [Column(TypeName = "money")]
            public decimal Budget { get; set; }
    
            [DataType(DataType.Date)]
            [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
            [Display(Name = "Start Date")]
            public DateTime StartDate { get; set; }
    
            public int? InstructorID { get; set; }
    
            public virtual Instructor Administrator { get; set; }
            public virtual ICollection<Course> Courses { get; set; }
        }
    
    }


    最后希望的模型定义图:

    做些总结汇总:

    1、模型中Properties如果名称为ID或者是类名+ID,则EF会自动将其变为主键;

    2、如果主键为int型,默认会定义为数据库自增长的类型,除非用 [DatabaseGenerated(DatabaseGeneratedOption.None)] 来明确告知不要;

    3、如果是1对1或0的对应关系,需要明确用[ForeignKey("XXXX")]来告知EF哪个是主表哪个是子表,不然会报异常;

    4、如果是多对1或0的对应关系,如果Properties是值类型,则需要用 问号 来定义可以为空;

    5、默认情况下,EF是开启联级删除(cascade delete),那么如果外键导致的联级删除出现多个

    例如:    A -> B 是 1对多,   A -> C 也是 1对多,  B 和 C 是多对多, 那么要删除 一个A,就需要联级删除先删除 B 和 C ,而要删除B 和 C 就要先删除 B 和 C 连接对应;

    这样就有两条路都到删除 B 和 C 的连接关系,这个是数据库所不允许的;

    那么只有两种方式:

           a) fluent API来申明关闭这个A的cascade delete;

           b) 把A -> B设置为 0,1对多,或者  A -> C 设置为 0,1对多, 即删除A时,不是删除B,而是把B里涉及到A的外键列值设置为NULL。

    6、如果是多对多的关系,则EF会自动新建一个表来存储多对多的关系;

    在上下文类中通过Fluent API来定义复杂模型关系及一些设定

    在上下文类中增加定义所有的实体,并通过Fluent API来定义一些设定;

    Fluent API可以用来设定绝大部分的模型关系及定义,但是也有一些不可以用Fluent API来设定,比如 MinimumLength

    因为MinimumLength 不会对数据库结构产生影响,而只是对客户端验证起作用;

    有点程序员比较喜欢用Fluent API,这样模型定义看起来“干净”很多,也可以用属性定义和Fluent API混合起来使用;

    以下的Fluent API定义了多对多的连接关系所采用的表名:

    using EFTest.Models;
    using System.Data.Entity;
    using System.Data.Entity.ModelConfiguration.Conventions;
    
    namespace EFTest.DAL
    {
        public class SchoolContext : DbContext
        {
            public SchoolContext() : base("SchoolContext")
            {
            }
            public DbSet<Student> Students { get; set; }
            public DbSet<Enrollment> Enrollments { get; set; }
            public DbSet<Course> Courses { get; set; }
            public DbSet<Instructor> Instructors { get; set; }
            public DbSet<Department> Departments { get; set; }
            public DbSet<OfficeAssignment> OfficeAssignments { get; set; }
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
                modelBuilder.Entity<Course>()
                        .HasMany(c => c.Instructors).WithMany(i => i.Courses)
                        .Map(t => t.MapLeftKey("CourseID")
                        .MapRightKey("InstructorID")
                        .ToTable("CourseInstructor"));
            }
        }
    }

    初始化种子数据

    模型调整好后,在MigrationsConfiguration.cs文件中Seed方法中放入测试种子数据:

    namespace EFTest.Migrations
    {
        using DAL;
        using Models;
        using System;
        using System.Collections.Generic;
        using System.Data.Entity;
        using System.Data.Entity.Migrations;
        using System.Linq;
    
        internal sealed class Configuration : DbMigrationsConfiguration<EFTest.DAL.SchoolContext>
        {
            public Configuration()
            {
                AutomaticMigrationsEnabled = false;
            }
    
            protected override void Seed(EFTest.DAL.SchoolContext context)
            {
                var students = new List<Student>
                {
                    new Student { FirstMidName = "Carson",   LastName = "Alexander",
                        EnrollmentDate = DateTime.Parse("2010-09-01") },
                    new Student { FirstMidName = "Meredith", LastName = "Alonso",
                        EnrollmentDate = DateTime.Parse("2012-09-01") },
                    new Student { FirstMidName = "Arturo",   LastName = "Anand",
                        EnrollmentDate = DateTime.Parse("2013-09-01") },
                    new Student { FirstMidName = "Gytis",    LastName = "Barzdukas",
                        EnrollmentDate = DateTime.Parse("2012-09-01") },
                    new Student { FirstMidName = "Yan",      LastName = "Li",
                        EnrollmentDate = DateTime.Parse("2012-09-01") },
                    new Student { FirstMidName = "Peggy",    LastName = "Justice",
                        EnrollmentDate = DateTime.Parse("2011-09-01") },
                    new Student { FirstMidName = "Laura",    LastName = "Norman",
                        EnrollmentDate = DateTime.Parse("2013-09-01") },
                    new Student { FirstMidName = "Nino",     LastName = "Olivetto",
                        EnrollmentDate = DateTime.Parse("2005-09-01") }
                };
    
                students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s));
                context.SaveChanges();
    
                var instructors = new List<Instructor>
                {
                    new Instructor { FirstMidName = "Kim",     LastName = "Abercrombie",
                        HireDate = DateTime.Parse("1995-03-11") },
                    new Instructor { FirstMidName = "Fadi",    LastName = "Fakhouri",
                        HireDate = DateTime.Parse("2002-07-06") },
                    new Instructor { FirstMidName = "Roger",   LastName = "Harui",
                        HireDate = DateTime.Parse("1998-07-01") },
                    new Instructor { FirstMidName = "Candace", LastName = "Kapoor",
                        HireDate = DateTime.Parse("2001-01-15") },
                    new Instructor { FirstMidName = "Roger",   LastName = "Zheng",
                        HireDate = DateTime.Parse("2004-02-12") }
                };
                instructors.ForEach(s => context.Instructors.AddOrUpdate(p => p.LastName, s));
                context.SaveChanges();
    
                var departments = new List<Department>
                {
                    new Department { Name = "English",     Budget = 350000,
                        StartDate = DateTime.Parse("2007-09-01"),
                        InstructorID  = instructors.Single( i => i.LastName == "Abercrombie").ID },
                    new Department { Name = "Mathematics", Budget = 100000,
                        StartDate = DateTime.Parse("2007-09-01"),
                        InstructorID  = instructors.Single( i => i.LastName == "Fakhouri").ID },
                    new Department { Name = "Engineering", Budget = 350000,
                        StartDate = DateTime.Parse("2007-09-01"),
                        InstructorID  = instructors.Single( i => i.LastName == "Harui").ID },
                    new Department { Name = "Economics",   Budget = 100000,
                        StartDate = DateTime.Parse("2007-09-01"),
                        InstructorID  = instructors.Single( i => i.LastName == "Kapoor").ID }
                };
                departments.ForEach(s => context.Departments.AddOrUpdate(p => p.Name, s));
                context.SaveChanges();
    
                var courses = new List<Course>
                {
                    new Course {CourseID = 1050, Title = "Chemistry",      Credits = 3,
                      DepartmentID = departments.Single( s => s.Name == "Engineering").DepartmentID,
                      Instructors = new List<Instructor>()
                    },
                    new Course {CourseID = 4022, Title = "Microeconomics", Credits = 3,
                      DepartmentID = departments.Single( s => s.Name == "Economics").DepartmentID,
                      Instructors = new List<Instructor>()
                    },
                    new Course {CourseID = 4041, Title = "Macroeconomics", Credits = 3,
                      DepartmentID = departments.Single( s => s.Name == "Economics").DepartmentID,
                      Instructors = new List<Instructor>()
                    },
                    new Course {CourseID = 1045, Title = "Calculus",       Credits = 4,
                      DepartmentID = departments.Single( s => s.Name == "Mathematics").DepartmentID,
                      Instructors = new List<Instructor>()
                    },
                    new Course {CourseID = 3141, Title = "Trigonometry",   Credits = 4,
                      DepartmentID = departments.Single( s => s.Name == "Mathematics").DepartmentID,
                      Instructors = new List<Instructor>()
                    },
                    new Course {CourseID = 2021, Title = "Composition",    Credits = 3,
                      DepartmentID = departments.Single( s => s.Name == "English").DepartmentID,
                      Instructors = new List<Instructor>()
                    },
                    new Course {CourseID = 2042, Title = "Literature",     Credits = 4,
                      DepartmentID = departments.Single( s => s.Name == "English").DepartmentID,
                      Instructors = new List<Instructor>()
                    },
                };
                courses.ForEach(s => context.Courses.AddOrUpdate(p => p.CourseID, s));
                context.SaveChanges();
    
                var officeAssignments = new List<OfficeAssignment>
                {
                    new OfficeAssignment {
                        InstructorID = instructors.Single( i => i.LastName == "Fakhouri").ID,
                        Location = "Smith 17" },
                    new OfficeAssignment {
                        InstructorID = instructors.Single( i => i.LastName == "Harui").ID,
                        Location = "Gowan 27" },
                    new OfficeAssignment {
                        InstructorID = instructors.Single( i => i.LastName == "Kapoor").ID,
                        Location = "Thompson 304" },
                };
                officeAssignments.ForEach(s => context.OfficeAssignments.AddOrUpdate(p => p.InstructorID, s));
                context.SaveChanges();
    
                AddOrUpdateInstructor(context, "Chemistry", "Kapoor");
                AddOrUpdateInstructor(context, "Chemistry", "Harui");
                AddOrUpdateInstructor(context, "Microeconomics", "Zheng");
                AddOrUpdateInstructor(context, "Macroeconomics", "Zheng");
    
                AddOrUpdateInstructor(context, "Calculus", "Fakhouri");
                AddOrUpdateInstructor(context, "Trigonometry", "Harui");
                AddOrUpdateInstructor(context, "Composition", "Abercrombie");
                AddOrUpdateInstructor(context, "Literature", "Abercrombie");
    
                context.SaveChanges();
    
                var enrollments = new List<Enrollment>
                {
                    new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Alexander").ID,
                        CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID,
                        Grade = Grade.A
                    },
                     new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Alexander").ID,
                        CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID,
                        Grade = Grade.C
                     },
                     new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Alexander").ID,
                        CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID,
                        Grade = Grade.B
                     },
                     new Enrollment {
                         StudentID = students.Single(s => s.LastName == "Alonso").ID,
                        CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID,
                        Grade = Grade.B
                     },
                     new Enrollment {
                         StudentID = students.Single(s => s.LastName == "Alonso").ID,
                        CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID,
                        Grade = Grade.B
                     },
                     new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Alonso").ID,
                        CourseID = courses.Single(c => c.Title == "Composition" ).CourseID,
                        Grade = Grade.B
                     },
                     new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Anand").ID,
                        CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID
                     },
                     new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Anand").ID,
                        CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID,
                        Grade = Grade.B
                     },
                    new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Barzdukas").ID,
                        CourseID = courses.Single(c => c.Title == "Chemistry").CourseID,
                        Grade = Grade.B
                     },
                     new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Li").ID,
                        CourseID = courses.Single(c => c.Title == "Composition").CourseID,
                        Grade = Grade.B
                     },
                     new Enrollment {
                        StudentID = students.Single(s => s.LastName == "Justice").ID,
                        CourseID = courses.Single(c => c.Title == "Literature").CourseID,
                        Grade = Grade.B
                     }
                };
    
                foreach (Enrollment e in enrollments)
                {
                    var enrollmentInDataBase = context.Enrollments.Where(
                        s =>
                             s.Student.ID == e.StudentID &&
                             s.Course.CourseID == e.CourseID).SingleOrDefault();
                    if (enrollmentInDataBase == null)
                    {
                        context.Enrollments.Add(e);
                    }
                }
                context.SaveChanges();
    
            }
    
    
            void AddOrUpdateInstructor(SchoolContext context, string courseTitle, string instructorName)
            {
                var crs = context.Courses.SingleOrDefault(c => c.Title == courseTitle);
                var inst = crs.Instructors.SingleOrDefault(i => i.LastName == instructorName);
                if (inst == null)
                    crs.Instructors.Add(context.Instructors.Single(i => i.LastName == instructorName));
            }
        }
    }

    数据库迁移升级

    在PM控制台输入: add-Migration ComplexDataModel

    这个时候如果直接输入 update-database  会报错,那是因为Course这个表里已经有数据,如果直接加不可为空的列是会报错的;

    所以需要在刚刚生成的带时间戳的 XXXXXXXXXXX_ComplexDataModel文件中如下面增加修改部分代码:

    即先插入一条临时的Department ,然后把现在所有的Course数据行在增加Department列的时候,指向这个临时Department.

                    CreateTable(
                    "dbo.CourseInstructor",
                    c => new
                        {
                            CourseID = c.Int(nullable: false),
                            InstructorID = c.Int(nullable: false),
                        })
                    .PrimaryKey(t => new { t.CourseID, t.InstructorID })
                    .ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: true)
                    .ForeignKey("dbo.Instructor", t => t.InstructorID, cascadeDelete: true)
                    .Index(t => t.CourseID)
                    .Index(t => t.InstructorID);
    
                // Create  a department for course to point to.
                Sql("INSERT INTO dbo.Department (Name, Budget, StartDate) VALUES ('Temp', 0.00, GETDATE())");
                //  default value for FK points to department created above.
                AddColumn("dbo.Course", "DepartmentID", c => c.Int(nullable: false, defaultValue: 1));
                //AddColumn("dbo.Course", "DepartmentID", c => c.Int(nullable: false));
                            
                AlterColumn("dbo.Course", "Title", c => c.String(maxLength: 50));

    最后执行 update-database 即可。

  • 相关阅读:
    南阳oj 82 迷宫寻宝(一)
    杭电 oj 1016 Prime Ring Problem
    杭电 oj 3350 #define is unsafe
    南阳oj 366 全排列 D的小L
    南阳oj 32 组合数
    部分和问题 南阳oj 1058
    HNUSTOJ 1516:Loky的烦恼
    HDU-1874 畅通工程续
    T-聊天止于呵呵
    P-残缺的棋盘
  • 原文地址:https://www.cnblogs.com/jacky-zhang/p/7442985.html
Copyright © 2020-2023  润新知