博客
关于我
EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public?
阅读量:392 次
发布时间:2019-03-05

本文共 2774 字,大约阅读时间需要 9 分钟。

前言

不知我们是否思考过一个问题,在关系映射中对于导航属性的访问修饰符是否一定必须为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
Orders { get; set; } = new List
(); }
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
Orders { get; set; } = new List
();

因为其为私有,若通过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
Orders { get; set; } = new List
();
HasMany(p => p.Orders).WithRequired(p => p.Customer).HasForeignKey(k => k.CustomerId);

那么在EF Core是否也和EF 6.x一样呢?我们继续来看看在EF Core中的情况,示例类为Blog和Post,这两个类已经在博客文章多次被用到,就不再给出,我们只关系导航属性访问修饰符的配置,如下:

private ICollection
Posts { get; set; } = new List
();
using (var context = new EFCoreDbContext())            {                var blogs = context.Blogs.Include("Posts").ToList();            }

此时会同样抛出异常,只不过异常信息大意是Posts不是Blog导航属性的一部分,对于基于字符串的Include方法,导航属性名称要以点分隔开,最终结果还是是找不到Posts导航属性,接下来我们将访问修饰符改为internal看看。

internal ICollection
Posts { get; set; } = new List
();
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,但是前提是必须显式配置映射关系,否则将抛出无法找到导航属性异常。

 

转载地址:http://dglzz.baihongyu.com/

你可能感兴趣的文章
pytest封神之路第二步 132个命令行参数用法
查看>>
Django认证系统并不鸡肋反而很重要
查看>>
快用Django REST framework写写API吧
查看>>
tep用户手册帮你从unittest过渡到pytest
查看>>
12张图打开JMeter体系结构全局视角
查看>>
Spring Boot 2.x基础教程:构建RESTful API与单元测试
查看>>
[UWP 自定义控件]了解模板化控件(1):基础知识
查看>>
UWP 自定义控件:了解模板化控件 系列文章
查看>>
[UWP]从头开始创建并发布一个番茄钟
查看>>
在 Azure 上执行一些简单的 python 工作
查看>>
WinUI 3 Preview 3 发布了,再一次试试它的性能
查看>>
使用命令把SpringBoot项目打包成可运行的jar包(简洁,操作性强)
查看>>
List数组排序
查看>>
VMware vSphere 离线虚拟机安装 BIND 9
查看>>
说说第一份工作
查看>>
dojo/request模块整体架构解析
查看>>
dojo/aspect源码解析
查看>>
Web性能优化:What? Why? How?
查看>>
Javascript定时器学习笔记
查看>>
dojo的发展历史
查看>>