编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

浅谈.NET EentityFramework的导航属性

wxchong 2024-10-19 15:34:52 开源技术 32 ℃ 0 评论

1 entityframwor是.net的orm组件(以下简称EF),基本上集成了orm所有功能之大成,并且开创了linq语法,使用lambda表达式对数据进行处理,在编程语言界可谓独领风骚,用来写后台不要太爽,用过都知道。

2 什么是导航属性呢?其实就是sql的子表关系在面向对象关系里的属性映射。在后台开发的数据处理中,多表关联查询是最最最常见的,但这却是orm里最难搞定的问题,不过EF使用一个称为Navigation(导航)的方式完美解决。 简单说比如表a{id,name }是主表,b{id,a_id,name}是子表,一对多的关系,a_id是b关联a的外键。很常见。在EF的实体里这样定义:


    public class A
    {
        [Key]
        public int ID { get; set; }          
    }
    public class B
    {
        [Key]
        public int ID { get; set; }        
        public int A_ID { get; set; }
        [ForeignKey("A_ID")]
        public A A { get; set; }
}

当b需要引用时a用include方法把a加载进来就行了。如

var list =DbContext.B.include(p=>p.A);

反过来,当a需要加载子表b的所有数据时,可以这样定义实体

    public class A
    {
        [Key]
        public int ID { get; set; }  
       public List<B> ListB { get; set; }
    }
    public class B
    {
        [Key]
        public int ID { get; set; }        
        public int A_ID { get; set; }
        [ForeignKey("A_ID")]
        public A A { get; set; }   
    }

同样用include方法把b加载进来就行了,如

var list =DbContext.A.where(p=>p.Name=="张三").include(p=>p.ListB).ToList();

3 导航是支持链表关系的,即可以无限制传递下去,当然现实中没人这样设计,一般关联到四五层关系。假设a和b有外键关联,b和c也有外键关联,那么c在加载数据时就可以写成

DbContext.C.Include(p=>p.B).ThenInclude(p=>p.A)

4 还有一种更加复杂的情况。即b有两个外键都是关联到a表。比如老师表 techer{id,姓名...},学生表 student{id,数学老师id,语文老师id...} 实体定义如下

public class Teacher
    {
        [Key]
        public int ID { get; set; }
        public string Name { get; set; }
        public List<Student> Students { get; set; }
    }
    public class Student
    {
        [Key]
        public int ID { get; set; }        
        public int Teacher_Yuwen_ID { get; set; }
        [ForeignKey("Teacher_ID")]
        public Teacher Yuwen { get; set; }

        public int Teacher_Shuxue_ID { get; set; }
        [ForeignKey("Teacher_Shuxue_ID")]
        public Teacher Shuxue { get; set; }
    }

那么,当teacher需要加载students时,如何指定关联外键是Teacher_Yuwen_ID 还是Teacher_Shuxue_ID呢?那就需要在DbContext初始化时指定一个。

  protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Teacher>().HasMany(p => p.Students).WithOne(p=>p.Yuwen);
        }

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表