• FluentAPI关系映射配置


    都有哪几种关系?

    1vs多,多vs多

    1. 概念or关系映射相关方法:

    1) 基本套路:this.Has***(o=>o.AAA).With***() 当前这个表和AAA属性的表关系是Has定义,With定义AAA表和这个表的关系

    BBBConfig{
        //这是1vs多的关系,1个AAA钟包含多个BBB
        public BBBConfig(){
            //这个BBB有多少个A属性;从后读A钟有多少B
            this.Has***(o=>o.A).With***();
        }
    }
    
    class AAA{
        public long Id{get;set;}
    }
    
    class BBB{
        public long Id{get;set;}
        public AAA A{get;set;}
    }

    2)  HasOptional() 有一个可选的(可以为空的)

    3)  HasRequired() 有一个必须的(不能为空的)

    4)  HasMany() 有很多的

    5)  WithOptional() 可选的

    6)  WithRequired() 必须的

    7)  WithMany() 很多的

    Eg:

    在AAA实体中配置this.HasRequired(o=>o.BBB).WithMany();

    表示在AAA中有且只有一个BBB,而在BBB中有对应多个AAA;

    在AAA实体中配置this.HasRequired(o=>o.BBB).WithRequired();

    表示在AAA中有且只有一个BBB,而在BBB中也只有一个对应的AAA

    练习:

    public class Class
        {
            public long Id { get; set; }
            public string Name { get; set; }
        //双向设计关系会让模型变的更难理解,同时可通过代码替代
        // Class clz = ctx.Classes.First(); 
        //var students =ctx.Students.Where(s => s.ClassId == clz.Id);
            public virtual ICollection<Student> Students { get; set; } = new List<Student>();
        }
    
    public class Student
        {
            public long Id { get; set; }
            public string Name { get; set; }
            public long ClassId { get; set; }
            public virtual Class Class { get; set; }
            public int Age { get; set; }
    }
    实体类
    public class ClassConfig:EntityTypeConfiguration<Class>
        {
            public ClassConfig() {
                ToTable("T_Classes");
            }
    }
    public class StudentConfig:EntityTypeConfiguration<Student>
        {
            public StudentConfig() {
                ToTable("T_Students");
            }
    }
    public class TestContent:DbContext
        {
            public TestContent() : base("name=connStr")
            {
                Database.SetInitializer<TestContent>(null);
            }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
                modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());
            }
    
            public DbSet<Class> Classes { get; set; }
            public DbSet<Student> Students { get; set; }
    }
    static void Main(string[] args)
            {
                using (TestContent ctx = new Tests.TestContent())
                {
                    ctx.Database.Log = (sql) =>
                    {
                        Console.WriteLine(sql);
                    };
                    Class clz = new Tests.Class();
                    clz.Name = "一年一班";
                    ctx.Classes.Add(clz);
    
                    Student s1 = new Tests.Student();
                    s1.Name = "小明";
                    s1.Class = clz;
                    s1.Age = 18;
                    ctx.Students.Add(s1);
                    ctx.SaveChanges();
    }
    }

    FluentAPI关系配置深入

    1. 建议在多的一端进行配置,从数据库角度外键也是建在多的一端

    public class StudentConfig:EntityTypeConfiguration<Student>
        {
            public StudentConfig() {
                ToTable("T_Students");
    //许多个学生只有一个班级,一个班级有需要个学生,外键是classId
                HasRequired(e => e.Class).WithMany().HasForeignKey(e => e.ClassId);
            }
           //如果 ClassId 可空,那么就要写成 :
    //this.HasOptional (s => s.Class).WithMany().HasForeignKey(s => s.ClassId) 
        }

    2. 一对多的关系在一端配置就可以了,当然两边都配也不错。

    3. 如果一张表中有两个指向另外一个表的外键怎么办?比如学生有“正常班级 Class”(不能空)和“小灶班级 XZClass”(可以空)两个班。如果用默认约定就会报错,怎么办?

    this.HasRequired(s => s.Class).WithMany().HasForeignKey(s => s.ClassId);
    this. HasOptional (s => s.XZClass).WithMany().HasForeignKey(s => s.XZClassId);

    多VS多关系配置

    class Student
    {
    public long Id { set; get; }
    public string Name { get; set; }
    public virtual ICollection<Teacher> Teachers { get; set; }=new List<Teacher>();
    }
    class Teacher
    {
    public long Id { set; get; }
    public string Name { get; set; }
    public virtual ICollection<Student> Students { get; set; }=new List< Student >();
    }
    实体对象
    class StudentConfig : EntityTypeConfiguration<Student>
    {
    public StudentConfig()
    {
    ToTable("T_Students");
    }
    }
    class TeacherConfig : EntityTypeConfiguration<Teacher>
    {
    public TeacherConfig()
    {
    ToTable("T_Teachers");
    //多个老师对应多个学生,多个学生对应多个老师;map映射关系表,
    //当前左键指的当前表
    this.HasMany(e => e.Students).WithMany(e => e.Teachers)
    .Map(m  =>
    m.ToTable("T_TeacherStudentRelations").MapLeftKey("TeacherId").MapRightKey("StudentId"));
    }
    }

    这样不用中间表建实体(也可以为中间表建立一个实体,其实思路更清晰),就可以完

    成多对多映射。当然如果中间关系表还想有其他字段,则要必须为中间表建立实体类。

  • 相关阅读:
    异常:java.io.IOException: Too many open files:
    转载 Servlet3.0中使用注解配置Servle
    Spring 源码从github导入源码到idea2016
    git 命令
    常用linux命令
    mysql优化常用语句
    mysql中in、not in、exists和not exists的区别
    mysql优化
    php常用的数据结构算法
    算法(一)
  • 原文地址:https://www.cnblogs.com/cuijl/p/6739754.html
Copyright © 2020-2023  润新知