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 ...
随机推荐
- 6.[leetcode] ZigZag Conversion
The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...
- HTML5 input date属性引起的探索——My97DatePicker(日期选择插件)
不得不说H5的input date属性真的好用,之前我写的http://www.cnblogs.com/tu-0718/p/6729274.html这篇博客里面也有提到,不过虽然移动端对H5的支持还是 ...
- synchronized的四种作用域以及不能被继承解析
synchronized是java中用于同步的关键字,其典型的作用域如下所示. 1 对象锁 @Slf4j public class SynchronizedExample1 { private fin ...
- ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)解决办法
一,报错原因及分析 mysql的这个报错的原因是mysql服务没有正确启动就是mysqld这个程序. mysql要想运行需要mysql和mysqld两个都启动才行 二,解决办法 右键我的电脑——> ...
- 一段JAVA代码了解多线程,JUC、CAS原子性操作。
@Test public void testPaceController_multiThread() throws InterruptedException { final PaceControlle ...
- 浅谈Google Chrome浏览器(操作篇)(上)
开篇概述 在上篇博客中详解Google Chrome浏览器(理论篇)一文中,主要讲解了Chrome 搜索引擎使用.Chrome安装和基本操作.Chrome 基本架构.多线程等原理性问题,这篇将重点讲解 ...
- SpringCloud系列——Config 配置中心
前言 Spring Cloud Config为分布式系统中的外部化配置提供了服务器端和客户端支持.有了配置服务器,您就有了一个中心位置来管理跨所有环境的应用程序的外部属性.本文记录实现一个配置中心.客 ...
- 在CentOS上安装owncloud企业私有云过程
## ownclud是什么? ## >ownCloud 是一个开源免费专业的私有云存储项目,它能帮你快速在个人电脑或服务器上架设一套专属的私有云文件同步网盘,可以像 Dropbox 那样实现文件 ...
- Java SimpleDateFormat处理日期与字符串的转换
1.为什么要使用SimpleDateFormat? 在Java中,如果我们想获取当前时间,一般会使用Date类的无参构造函数,如下所示,我们获取到当前时间并输出: import java.util.D ...
- 分布式系统唯一ID的生成方案讨论
在分布式系统下唯一id问题,就是id咋生成?比如分表分库,因为要是一个表分成多个表之后,每个表的id都是从1开始累加自增长,那是不对的.举个例子,一个表拆分为了2张表,每个表的id都从1开始累加,这个 ...