EF--主外键关系导航属性

  • 数据准备
    公司表Company和员工表Employee两张表创建主外键强关系,员工表Employee的Company_ID是公司表Company的外键,如下图所

  • 解读主外键生成的实体特殊性

Company实体--主外键关系的话,EF生成的实体,主表Company实体有个子表Employee的集合,注意这个集合是virtual虚拟的

Employee实体--子表里面还有个主表Company的实例,引用属性,注意主表实体Company也是virtual虚拟的

  • 导航属性是延迟查询

我们看到我们只查询公司ID是“0000000001”的公司,并没有主动去查询这个公司下面的员工并没有生成查询员工的sql,但是当我们遍历公司员工company.Employee的时候EF主动帮我们查询了得到这个公司下面的员工,所以证明导航属性是延迟查询,只有在真正使用的时候才去查询“0000000001”这个公司下面的员工,条件是virtaul属性+默认配置

public class EFNavTest
{
    public static void Show()
    {
        {
            using (SchoolDBEntities dbContext = new SchoolDBEntities())
            {
                var companyList = dbContext.Set<Company>().Where(c => c.Company_ID == "0000000001");
                foreach (var company in companyList)//只查company
                {
                    Console.WriteLine(company.Company_Name);
                    foreach (var employee in company.Employees)
                    {
                        Console.WriteLine(employee.Employee_Name);
                    }
                }
                Console.Read();
            }
        }
    }
}

  • 关闭延迟加载,子表的数据就没有了

dbContext.Configuration.LazyLoadingEnabled = false;

{
    using (SchoolDBEntities dbContext = new SchoolDBEntities())
    {
        dbContext.Configuration.LazyLoadingEnabled = false;//关闭延迟查询
        var companyList = dbContext.Set<Company>().Where(c => c.Company_Id == 02);
        foreach (var company in companyList)//只查company
        {
            Console.WriteLine(company.Company_Name);
            foreach (var employee in company.Employees)
            {
                Console.WriteLine(employee.Employee_Name);
            }
        }
    }
}

  • Include预先加载

预先加载,Include查询主表Company时就把子表数据Employee一次性查出来,和上面导航属性的懒加载不同,不同之处在于上面是当使用company.Employee的时候EF主动帮我们查询了得到这个公司下面的员工,而Include查询主表Company时就把子表数据Employee一次性查出来了不管你有没有用,我们从EF生成的sql语句就能看出来是个左外连接,它是把“0000000001”这个公司和它下面的员工一下都查询出来了

{
    //3、预先加载,Include查询主表时就把子表数据一次性查出来
    using (SchoolDBEntities dbContext = new SchoolDBEntities())
    {
        dbContext.Configuration.LazyLoadingEnabled = false;//是否关闭无所谓
        var companyList = dbContext.Set<Company>().Include("Employees").Where(c => c.Company_Id == "0000000001");
        foreach (var company in companyList)//只查company
        {
            Console.WriteLine(company.Company_Name);
            foreach (var employee in company.Employees)            {
                Console.WriteLine(employee.Employee_Name);            }
        }
    }
}

  • 关闭延迟查询后,不想使用Include一次性查询子表的数据,只是需要子表的数据,才要查询,Collection可以显式加载

当执行了dbContext.Entry<Company>(company).Collection(c => c.Employees).Load();这句代码,就会生成查询该公司下的员工的sql语句,就会查询该公司的员工

{
    //4、关闭延迟查询后,如果需要子表数据,可以显示加载
    using (SchoolDBEntities dbContext = new SchoolDBEntities())
    {
        dbContext.Configuration.LazyLoadingEnabled = false;
        var companyList = dbContext.Set<Company>().Where(c => c.Company_Id == "0000000001");
        foreach (var company in companyList)//只查company
        {
             Console.WriteLine(company.Company_Name);
            dbContext.Entry<Company>(company).Collection(c => c.Employees).Load();
            foreach (var employee in company.Employees)
            {
                Console.WriteLine(employee.Employee_Name);
            }
        }
    }
}

  • 闭延迟查询后,如果需要主表数据,Reference可以显式加载

当执行了dbContext.Entry(employee).Reference(s => s.Company).Load();这句代码,就会生成查询该员工的公司的sql语句,就会查询该员工的公司

//5、关闭延迟查询后、如果需要主表数据,可以显示加载
using (SchoolDBEntities dbContext = new SchoolDBEntities())
{
    dbContext.Configuration.LazyLoadingEnabled = false;
    var employeeList = dbContext.Set<Employee>().Where(s => s.Employee_ID == "0000000001");
    foreach (var employee in employeeList)
    {
        Console.WriteLine(employee.Employee_Name);
        dbContext.Entry<Employee>(employee).Reference(s => s.Company).Load();
        string companyName = employee.Company.Company_Name;
        Console.WriteLine(companyName);
    }
}

  • 结论

根据上面的阐述,可以表与表非主外键关系建立导航属性,一般来说,主表有个子表的集合导航属性(像上述的public virtual ICollection<Employee> Employees { get; set; },注意必须是virtual虚拟的),子表里面还有个主表的实例(像上述的 public virtual Company Company { get; set; },注意必须是virtual虚拟的),引用属性,就可以了

原文地址:https://www.cnblogs.com/menglin2010/p/12255343.html

时间: 2024-10-09 23:39:39

EF--主外键关系导航属性的相关文章

MySQL创建数据表并建立主外键关系

为mysql数据表建立主外键需要注意以下几点: 需要建立主外键关系的两个表的存储引擎必须是InnoDB. 外键列和参照列必须具有相似的数据类型,即可以隐式转换的数据类型. 外键列和参照列必须创建索引,如果外键列不存在索引,mysql将自动创建索引. 一.SQL语句创建数据表并设置主外键关系 create table demo.ChineseCharInfo ( ID int not null auto_increment, Hanzi varchar(10) not null, primary

SQL SERVER中获取表间主外键关系

sql server 2008中的主外键关系获取方式: 转自:http://www.cnblogs.com/ke10/archive/2012/06/11/2544655.html SELECT OBJECT_NAME(con.constid) '关系名' ,OBJECT_NAME(sf.fkeyid) '主键表' ,fcol.name '主键' ,OBJECT_NAME(sf.rkeyid) '外键表' ,rcol.name '外键',st.name'数据类型'FROM sysforeignk

Hinernate进行mysql数据库的逆向工程无法生成主外键关系

(1)我们在进行SSH开发大※的项目的时候,使用myeclipse自带的hibernate的逆向工程工具时,发现竟然无法生成one-to-one  one-to-many等的主外键关系,明明的数据库建时已经有主外键关系了.为啥逆向生成时就不行了呢? (2)首先说一下,我使用的是PHP开发环境Appserv自带的MySQL数据库,不是单独安装的: (3)这是因为数据库引擎的问题, 我们可以在sql命令行中输入命令:show engines; 可以看到default默认的是MyISAM: (3)"M

Sql Server有主外键关系时添加、删除数据

当表之间有主外键关系时删除数据会被约束,添加.删除失败 解决办法,我们可以先把主外键关系的检查约束给关掉 → 然后删除数据 → 之后再把约束打开 查询出关掉所有外键约束的语句 SELECT 'ALTER TABLE ' + O.NAME + ' NOCHECK CONSTRAINT [' + F.NAME + '];' AS COMMAND FROM SYS.FOREIGN_KEYS F INNER JOIN SYS.ALL_OBJECTS O ON F.PARENT_OBJECT_ID = O

通过SQL脚本来查询SQLServer 中主外键关系

在SQLServer中主外键是什么,以及主外键如何创建,在这里就不说了,不懂的可以点击这里,这篇文章也是博客园的博友写的,我觉得总结的很好: 此篇文章主要介绍通过SQL脚本来查看Sqlserver中主外键关系: SELECT f.name AS '关系名称', OBJECT_NAME(f.parent_object_id) AS '表名称', COL_NAME(fc.parent_object_id,fc.parent_column_id) AS '字段名称', OBJECT_NAME (f.r

EF之Code First设置主外键关系(一)

指定类外键有注释(DataAnnotation)和FluentAPI两种方式,下面我们主要使用DataAnnotation指定外键关系 第一种方式 //1-指定导航属性,会自动生成外键,命名规则为:“对象名称_主键名” public class TUsers { [Key] public int UserId { get; set; } public string Account { get; set; } public string Password { get; set; } public

Entity Framework Code First主外键关系映射约定

本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个不同表之间可以存在外键依赖关系,一个表自身也可以有自反关系(表中的一个字段引用主键,从而也是外键字段). Entity Framework Code First默认多重关系的一些约定规则: 一对多关系:两个类中分别包含一个引用和一个集合属性,也可以是一个类包含另一个类的引用属性,或一个类包含另一个类

关于表的主外键关系练习 师生 分数表

--创建三个表 --表一:学生表 student--学号:code int (主键)从1开始--姓名:name varchar(50)--性别:sex char(10)--班级:banji char(10)--语文教师编号:yujiao int --数学教师编号:yujiao int --英语教师编号:yujiao int --表二:教师表 teacher--教师名字:name --教师编号:code int (主键) 从1001开始--负责课程:lesson char(10)(语文.数学.英语

SQL Server数据库中导入导出数据及结构时主外键关系的处理

2015-01-26 软件开发中,经常涉及到不同数据库(包括不同产品的不同版本)之间的数据结构与数据的导入导出.处理过程中会遇到很多问题,尤为突出重要的一个问题就是主从表之间,从表有外检约束,从而导致部分数据无法导入. 情景一.同一数据库产品,相同版本 此种情况下源数据库与目标数据库的数据结构与数据的导入导出非常简单. 方法1:备份源数据库,恢复到目标数据库即完成. 方法2:使用SQL Sever数据库自带的[复制数据库]功能或者[导入数据]功能按照向导操作即可. 情景二.同一数据库产品,不同版