EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public?
前言
不知我们是否思考过一个问题,在关系映射中对于导航属性的访问修饰符是否一定必须为public呢?如果从未想过这个问题,那么我们接下来来探讨这个问题。
EF 6.x和EF Core 何种情况下必须配置映射关系?
在EF 6.x中我们创建如下示例类。
public partial class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public ICollection<Order> Orders { get; set; } = new List<Order>();
}
public class Order : BaseEntity
{
public int Quantity { get; set; }
public string Code { get; set; }
public decimal Price { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; }
}
上述我们不显式配置映射关系,EF和EF Core会根据约定来配置,同样达到如我们期望的,无论是EF 6.x还是EF Core中通过Inlcude进行显式加载有两种方式,一种是基于字符串,另外一种则是通过lamda表达式的方式(命名空间存在于System.Data.Entity),接下来我们来看下:
using (var ctx = new EfDbContext())
{
ctx.Database.Log = Console.WriteLine; var customers = ctx.Customers.Include(d => d.Orders).ToList();
};

这样是我们一直以来最正常的操作,如前言所叙,那么导航属性难道必须是public吗?接下来我们来试试。我们尝试将Orders导航属性配置成如下私有的。
private ICollection<Order> Orders { get; set; } = new List<Order>();
因为其为私有,若通过lambda表达式肯定是访问受限制,那么我们改为通过基于字符串的方式来显式加载,如下:
using (var ctx = new EfDbContext())
{
ctx.Database.Log = Console.WriteLine; var customers = ctx.Customers.Include("Orders").ToList();
};

如上则抛出异常找不到Orders导航属性,是不是到此下结论而定导航属性必须是public呢?访问修饰符除了public,还有protected、internal以及protected internal。通过实践验证若导航属性为private、protected访问修饰符肯定不行,若为internal和protected internal则可以,前提是必须显式配置映射关系,否则也不行,如下:
protected internal ICollection<Order> Orders { get; set; } = new List<Order>();
HasMany(p => p.Orders).WithRequired(p => p.Customer).HasForeignKey(k => k.CustomerId);
那么在EF Core是否也和EF 6.x一样呢?我们继续来看看在EF Core中的情况,示例类为Blog和Post,这两个类已经在博客文章多次被用到,就不再给出,我们只关系导航属性访问修饰符的配置,如下:
private ICollection<Post> Posts { get; set; } = new List<Post>();
using (var context = new EFCoreDbContext())
{
var blogs = context.Blogs.Include("Posts").ToList();
}

此时会同样抛出异常,只不过异常信息大意是Posts不是Blog导航属性的一部分,对于基于字符串的Include方法,导航属性名称要以点分隔开,最终结果还是是找不到Posts导航属性,接下来我们将访问修饰符改为internal看看。
internal ICollection<Post> Posts { get; set; } = new List<Post>();
using (var context = new EFCoreDbContext())
{
var blogs = context.Blogs.Include(d => d.Posts).ToList();
//var blogs1 = context.Blogs.Include("Posts").ToList();
}

此时我们再来显式配置映射关系则好使。
builder.HasMany(m => m.Posts)
.WithOne(o => o.Blog);

总结
对于EF和EF Core中通过Include方法进行显式加载具体实现没有去看源码,完全通过实践得到的结论是:无论是EntityFramework还是EntityFramework Core,在关系映射中导航属性不一定必须是public修饰符,也可以为internal和protected internal,但是前提是必须显式配置映射关系,否则将抛出无法找到导航属性异常。

EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public?的更多相关文章
- 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制
你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...
- ASP.NET Core EF 查询获取导航属性值,使用Include封装
// 引用 using Microsoft.EntityFrameworkCore; // 摘要: // Specifies related entities to include in the qu ...
- Hibernate关系映射中的注解
一.@Entity 写在映射表的类上面,表示这是映射来的实体 二.@Id @Column(name = "fid", nullable = false) @Basic @Colum ...
- JPA实体关系映射:@ManyToMany多对多关系、@OneToMany@ManyToOne一对多多对一关系和@OneToOne的深度实例解析
JPA实体关系映射:@ManyToMany多对多关系.@OneToMany@ManyToOne一对多多对一关系和@OneToOne的深度实例解析 今天程序中遇到的错误一 org.hibernate.A ...
- JPA 对象关系映射之关联关系映射策略
关联关系映射 关联关系映射,是映射关系中比较复杂的一种映射关系,总的说来有一对一.一对多和多对多几种关系.细分起来他们又有单向和双向之分.下面我们逐一介绍一下. 回页首 单向 OneToOne 单向一 ...
- 问题记录:EntityFramework 一对一关系映射
EntityFramework 一对一关系映射有很多种,比如主键作为关联,配置比较简单,示例代码: public class Teacher { public int Id { get; set; } ...
- 死去活来,而不变质:Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?
写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?>博文中, ...
- Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?
Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射? 写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:D ...
- entityframework学习笔记--007-实体数据建模基础之继承关系映射TPT
Table per Type Inheritance (TPT)建模 1.假设你有两张表与一张公共的表密切相关,如图7-1所示,Businiss表与eCommerce表.Retail表有1:0...1 ...
随机推荐
- volatile关键字的特性及证明
volatile是java虚拟机提供的轻量级的同步机制 JMM(Java内存模型)是围绕着并发编程中原子性.可见性.有序性这三个特征来建立的 原子性:一个操作或多个操作要么全部执行完成且执行过程不被中 ...
- AI - TensorFlow - 张量(Tensor)
张量(Tensor) 在Tensorflow中,变量统一称作张量(Tensor). 张量(Tensor)是任意维度的数组. 0阶张量:纯量或标量 (scalar), 也就是一个数值,例如,\'Howd ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之二 || 后端项目搭建
前言 至于为什么要搭建.Net Core 平台,这个网上的解释以及铺天盖地,想了想,还是感觉重要的一点,跨平台,嗯!没错,而且比.Net 更容易搭建,速度也更快,所有的包均有Nuget提供,不再像以前 ...
- Linux - 通过LVM对磁盘进行动态扩容
目录 1 LVM是什么 1.1 概念解释 1.2 为什么用LVM 1.2.1 不使用LVM时的扩容思路 1.2.2 使用LVM时的扩容思路 1.3 名词解释 2 普通的挂载磁盘方法 2.1 创建分区的 ...
- 尴尬的事情又发生Newtonsoft.Json vs Protobuf.net
写程序做下性能测试都是例行的事情了,一般在普通电脑上测试一下如果比较理想那基本不出什么意外!但世事难料,代码写得不好经常担心CPU不够用,其实写得好但不能完全发挥出CPU资源的优势更是一件悲剧的事情! ...
- 运输问题的+Leapms模型
运输问题的+Leapms模型 运输问题是本科教课书中的一个经典章节.运输问题的线性规划模型非常简单,而且求解难度极小. 问题 一个公司生产并销售一种产品.该公司有m个产地.n个销地.产地 i 的供给量 ...
- DSAPI TreeView节点增删简化操作
将一行或多行字符串添加到TreeView控件. 函数: 控件.TreeView控件.添加路径节点到TreeView(要添加节点的TreeView控件,字符串或字符串数组) 示例:将一个多行文本添加到T ...
- Windows Server 2008 中iis反向代理设置
1.安装 IIS(Windows专业版自带,如果是server版系统,需要通过功能管理器安装(无需下载)) urlrewrite插件,https://www.iis.net/downloads/mic ...
- SQL Server 一列或多列重复数据的查询,删除(转载)
转载来源:https://www.cnblogs.com/sunxi/p/4572332.html 业务需求 最近给公司做一个小工具,把某个数据库(数据源)的数据导进另一个数据(目标数据库).要求导入 ...
- [TCP/IP] 传输层-TCP和UDP的使用场景
传输层-TCP和UDP应用场景 TCP(传输控制协议) 需要将要传输的文件分段传输,建立会话,可靠传输,流量控制 UDP(用户报文协议) 一个数据包就能完成数据通信,不需要建立会话,不分段,不用流量控 ...