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 ...
随机推荐
- [AI开发]视频多目标跟踪高级版(离自动驾驶又‘近’了一点点)
**本文恐怕不是完全的标题党** 视频多目标跟踪需要解决的关键点是前后两帧之间的Target Association,这是最难的环节(没有之一).第T帧检测到M个目标,第T+S(S>=1)帧检测 ...
- 经典排序算法 — C#版本(中)
归并排序比较适合大规模得数据排序,借鉴了分治思想. 归并排序原理 自古以来,分久必合合久必分. 我们可以这样理解归并排序,分-分到不能分为止,然后合并. 使用递归将问题一点一点分解,最后进行合并. 分 ...
- ArrayBlockQueue源码解析
清明节和朋友去被抖音带火的一个餐厅,下午两点钟取晚上的号,前面已经有十几桌了,四点半餐厅开始正式营业,等轮到我们已经近八点了.餐厅分为几个区域,只有最火的区域(在小船上)需要排号,其他区域基本上是随到 ...
- Optimizing Java笔记:高级垃圾回收
原书地址:https://www.safaribooksonline.com/library/view/optimizing-java/9781492039259/ 感觉挺不错的一本书,断断续续在读. ...
- 使用 Moq 测试.NET Core 应用 -- Mock 行为
第一篇文章, 关于Mock的概念介绍: https://www.cnblogs.com/cgzl/p/9294431.html 第二篇文章, 关于方法Mock的介绍: https://www.cnbl ...
- SpringSecurity自定义AuthenticationProvider和AuthenticationFilter
AuthenticationProvider 默认实现:DaoAuthenticationProvider 授权方式提供者,判断授权有效性,用户有效性,在判断用户是否有效性,它依赖于UserDetai ...
- Spring Boot系列(一) Spring Boot准备知识
本文是学习 Spring Boot 的一些准备知识. Spring Web MVC Spring Web MVC 的两个Context 如下图所示, 基于 Servlet 的 Spring Web M ...
- 一套代码小程序&Web&Native运行的探索02
接上文:一套代码小程序&Web&Native运行的探索01,本文都是一些探索性为目的的研究学习,在最终版输出前,内中的内容可能会有点乱 参考: https://github.com/f ...
- el-upload 上传文件和上传图片的基本用法
el-upload 上传excel <template> <el-form :model="form"> <el-form-item label=&q ...
- C#语法——反射,架构师的入门基础。
前言 编程其实就是写代码,而写代码目的就是实现业务,所以,语法和框架也是为了实现业务而存在的.因此,不管多么高大上的目标,实质上都是业务. 所以,我认为不要把写代码上升到科学的高度.上升到艺术就可以了 ...