前言

不知我们是否思考过一个问题,在关系映射中对于导航属性的访问修饰符是否一定必须为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?的更多相关文章

  1. 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制

    你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...

  2. ASP.NET Core EF 查询获取导航属性值,使用Include封装

    // 引用 using Microsoft.EntityFrameworkCore; // 摘要: // Specifies related entities to include in the qu ...

  3. Hibernate关系映射中的注解

    一.@Entity 写在映射表的类上面,表示这是映射来的实体 二.@Id @Column(name = "fid", nullable = false) @Basic @Colum ...

  4. JPA实体关系映射:@ManyToMany多对多关系、@OneToMany@ManyToOne一对多多对一关系和@OneToOne的深度实例解析

    JPA实体关系映射:@ManyToMany多对多关系.@OneToMany@ManyToOne一对多多对一关系和@OneToOne的深度实例解析 今天程序中遇到的错误一 org.hibernate.A ...

  5. JPA 对象关系映射之关联关系映射策略

    关联关系映射 关联关系映射,是映射关系中比较复杂的一种映射关系,总的说来有一对一.一对多和多对多几种关系.细分起来他们又有单向和双向之分.下面我们逐一介绍一下. 回页首 单向 OneToOne 单向一 ...

  6. 问题记录:EntityFramework 一对一关系映射

    EntityFramework 一对一关系映射有很多种,比如主键作为关联,配置比较简单,示例代码: public class Teacher { public int Id { get; set; } ...

  7. 死去活来,而不变质:Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?

    写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?>博文中, ...

  8. Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?

    Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射? 写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:D ...

  9. entityframework学习笔记--007-实体数据建模基础之继承关系映射TPT

    Table per Type Inheritance (TPT)建模 1.假设你有两张表与一张公共的表密切相关,如图7-1所示,Businiss表与eCommerce表.Retail表有1:0...1 ...

随机推荐

  1. 利用requirejs实现vue的模块化开发

    通常vue都是搭配webpack+vue-cli使用的 如果不在nodejs环境下开发web应用呢? 这里提出一个解决方案: 1.加载requirejs,并且指定main函数 <script d ...

  2. Java Thread.join的作用和原理

    很多人对Thread.join的作用以及实现了解得很少,毕竟这个api我们很少使用.这篇文章仍然会结合使用及原理进行深度分析 内容导航 Thread.join的作用 Thread.join的实现原理 ...

  3. 实现iframe高度自适应

    iframe高度自适应使用场景是类似于微博,新闻等点击加载更多这种功能实现,要求iframe的高度能够跟随内容的变化而变化. 父html文件,也就是引用ifram的文件 src="blog/ ...

  4. 支持向量机(SVM)之数学公式详细推导

    一.概述 1.含义: 支持向量机(support vector machine,SVM)是一种二类分类器,它的基本模型是定义在特征空间上的间隔最大化的线性分类器,通过引入核函数,也可以作为非线性分类器 ...

  5. 网络协议 21 - RPC 协议(中)- 基于 JSON 的 RESTful 接口协议

        上一节我们了解了基于 XML 的 SOAP 协议,SOAP 的 S 是啥意思来着?是 Simple,但是好像一点儿都不简单啊! 传输协议问题     对于 SOAP 来讲,比如我创建一个订单, ...

  6. ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)

    早就听说ASP.NET Core 3.0中引入了gRPC的服务模板,正好趁着家里电脑刚做了新系统,然后装了VS2019的功夫来体验一把.同时记录体验的过程.如果你也想按照本文的步骤体验的话,那你得先安 ...

  7. string类的几种方法

    string str="123abc456";int i=3;1 取字符串的前i个字符   str=str.Substring(0,i); // or  str=str.Remov ...

  8. Jenkins|简单Job配置|启动脚本|测试报告

    目录 1.Jenkins安装 2.Jenkins启动脚本 3.节点配置 4.任务配置 5.集成HTML测试报告 1.Jenkins安装 操作环境:Ubuntu jenkins针对windows,ubu ...

  9. 一个用来爬小说的简单的Node.js爬虫

    小说就准备点天下霸唱和南派三叔的系列,本人喜欢看,而且数据也好爬.貌似因为树大招风的原因,这两作者的的书被盗版的很多,乱改的也多.然后作者就直接在网上开放免费阅读了,还提供了官网,猜想作者应该是允许爬 ...

  10. 强化学习(九)Deep Q-Learning进阶之Nature DQN

    在强化学习(八)价值函数的近似表示与Deep Q-Learning中,我们讲到了Deep Q-Learning(NIPS 2013)的算法和代码,在这个算法基础上,有很多Deep Q-Learning ...