• 【译】第26节---配置一对多关系


    原文:http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx

    本节,我们将学习如何在Code First中配置两个实体之间的一对多关系。

    举一个Student和Standard(年级)实体的例子,其中,一个Standard可以包括许多Student。 所以Student与Standard实体之间的关系将是一对多的。

    使用DataAnnotation配置一对多关系

    来看下面Student与Standard实体:

    public class Student
    {
        public Student() { }
    
        public int StudentId { get; set; }
        public string StudentName { get; set; }
    
        public virtual Standard Standard { get; set; }
    }
           
    public class Standard
    {
        public Standard()
        {
            Students = new List<Student>();
        }
        public int StandardId { get; set; }
        public string Description { get; set; }
    
        public virtual ICollection<Student> Students { get; set; }
    }

    上述示例中,Student实体包括导航属性Standard,Standard实体包括Student的集合属性。 这是形成一对多关系的默认约定。

    如果实体类遵循此约定,则我们不需要使用DataAnnotations或Fluent API配置一对多关系。

    EF Code First将通过在Student表中添加Standard_StandardId列来创建一对多关系,如下所示:

    实体包括外键Id属性:

    建议在实体类中包含外键属性。 例如,Student实体包含自动变为foreignkey属性的StandardId属性,因为它符合外键<Type Name> Id的约定。

    如果foreignkey属性名称不符合约定,例如,Student实体对于Standard实体使用了不同名称的外键(不是StandardId),那么我们需要在属性上应用ForeignKey属性。

    例如,以下Student实体包括StandardRefId属性:

    public class Student
    {
        public Student() { }
    
        public int StudentId { get; set; }
        public string StudentName { get; set; }
    
            public int StdandardRefId { get; set; }
            
        [ForeignKey("StandardRefId")]
        public virtual Standard Standard { get; set; }
    }
           
    public class Standard
    {
        public Standard()
        {
            Students = new List<Student>();
        }
        public int StandardId { get; set; }
        public string Description { get; set; }
    
        public virtual ICollection<Student> Students { get; set; }
    }

    上述示例中,ForeignKey属性应用于Standard导航属性以指定Standard属性的foreignkey属性名称。所以EF将创建一个StandardRefId列作为FK,如下所示:

    使用Fluent API配置一对多关系

    这里,我们将学习使用Fluent API的Student和Standard实体之间的一对多关系。

    让我们为以下Student和Standard实体配置一对多关系:

    public class Student
    {
        public Student(){ }
    
        public int StudentId { get; set; }
        public string StudentName { get; set; }
    
        public int StandardId { get; set; }
    
        public virtual Standard Standard { get; set; }
    }
           
    public class Standard
    {
        public Standard()
        {
            StudentsList = new List<Student>();
        }
        public int StandardId { get; set; }
        public string Description { get; set; }
    
        public virtual ICollection<Student> Students { get; set; }
    }

    你可以按照一下代码进行配置:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
            //one-to-many 
            modelBuilder.Entity<Student>()
                        .HasRequired<Standard>(s => s.Standard) // Student entity requires Standard 
                        .WithMany(s => s.Students); // Standard entity includes many Students entities
    
    }

    假设Student和Standard实体类没有遵循外键的Code First约定:

    public class Student
    {
        public Student(){ }
    
        public int StudentId { get; set; }
        public string StudentName { get; set; }
    
        //StdId is not following code first conventions name
        public int StdId { get; set; }
    
        public virtual Standard Standard { get; set; }
    }
           
    public class Standard
    {
        public Standard()
        {
            StudentsList = new List<Student>();
        }
        public int StandardId { get; set; }
        public string Description { get; set; }
    
        public virtual ICollection<Student> Students { get; set; }
    }

    所以,你可以通过Fluent API使用Student实体类配置一对多关系,如下所示:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
            //one-to-many 
            modelBuilder.Entity<Student>()
                        .HasRequired<Standard>(s => s.Standard)
                        .WithMany(s => s.Students)
                        .HasForeignKey(s => s.StdId);
    
    }

    可以看到,modelBuilder.Entity <Student>().HasRequired <Standard>(s => s.Standard)指定Student实体需要NotNull标准导航属性。

    .WithMany(s => s.Students).HasForeignKey(s => s.StdId)指定Standard实体可以包括多个Student在学生集合属性中,外键是StdId。

    另一种可行的方式:我们也可以从Standard实体开始:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
            //configure one-to-many
            modelBuilder.Entity<Standard>()
                        .HasMany<Student>(s => s.Students) //Standard has many Students
                        .WithRequired(s => s.Standard)  //Student require one Standard
                        .HasForeignKey(s => s.StdId);//Student includes specified foreignkey property name for Standard
    }

     上面的代码将创建以下数据库:

    注意StdId不为空列。 所以每次添加或更新Student时,都必须为Student实体指定Standard。

    一对多关系中的可空外键:

    使用HasOptional方法代替HasRequired方法使外键列为空。

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
            //one-to-many 
            modelBuilder.Entity<Student>()
                        .HasOptional<Standard>(s => s.Standard)
                        .WithMany(s => s.Students)
                        .HasForeignKey(s => s.StdId);
    
    }

    下节学习多对多关系的配置。

  • 相关阅读:
    HDU-1875-畅通工程再续(最小生成树)
    HDU-1325-Is It A Tree?(并查集+有向树)
    HDU-2473-Junk-Mail Filter(并查集删除)
    HDU-1233-还是畅通工程(最小生成树)
    POJ-2492-A Bug's Life(并查集分类)
    asp.net core 中KindEditor的使用
    使用FormsAuthenticationTicket进行登陆验证
    c#生成随机字符串
    string.Format对C#字符串格式化
    在Ubuntu上使用noip动态域名的方法(ddns)
  • 原文地址:https://www.cnblogs.com/talentzemin/p/7284923.html
Copyright © 2020-2023  润新知