Entity Framework Core 2.1 Preview1 新增功能简介

两个星期前,微软发布了EF Core 2.1 Preview 1,同时还发布了.NET Core 2.1 Preview 1和ASP.NET Core 2.1 Preview 1;EF Core 2.1 Preview 1 除了许多小改进和超过100种产品错误修复之外,还包括几个常用的新功能,今天我为您详细介绍这些新功能的部分内容。

实体构造函数参数

EF.Core 2.1开始支持在实体的构造函数的实体中转入参数,目前支持的类型如下:

实体属性

IOC容器中注册的服务

当前的DbContext

当前实体的元数据

实体属性

在某些情况下为了保证数据的安全性,将属性改为只读,在构造函数中传递属性的值,框架通过参数与属性匹配关系,将数据行中属性的值作为参数传递给构造函数。

例如下面的实体:

public class Order { public Order(int orderID, string customerID, DateTime? orderDate) { OrderID = orderID; CustomerID = customerID; OrderDate = orderDate; } public int OrderID { get; } public string CustomerID { get; } public DateTime? OrderDate { get; } }

其中参数与属性的配置规则如下:

参数的类型与属性的类型一致;

属性名与参数名除首字母不区分大小写之外,其它字符一致,并且可以使用 _ 、m_做为前缀,使用OrderID属性来举例,存在如下匹配规则:

属性名 参数名
OrderID   OrderID  
OrderID   orderID  
_OrderID   orderID  
_OrderID   OrderID  
m_OrderID   OrderID  
m_OrderID   OrderID  

具体的匹配规则可以见Github上面的源代码:
不过我认识后面四种模式有待斟酌的,在.Net开发规范,应该没有人将公有的属性名使用 _m_作为前缀。

IOC容器中注册的服务

在实体的构造函数的中,可以将注册的服务作为参数。

示例代码:

public class Order { private ILazyLoader _lazyLoader; public Order(ILazyLoader lazyLoader) { this._lazyLoader = lazyLoader; } public int OrderID { get; set; } public string CustomerID { get; set; } private ICollection<OrderDetail> _orderDetails; public ICollection<OrderDetail> OrderDetails { get => _lazyLoader.Load(this, ref _orderDetails); set => _orderDetails = value; } } }

其中ILazyLoader是EF Core框架在容器中注册的一个服务,通过实体的构造函数中传入,实现导航属性的赖加载(关于ILazyLoader的具体使用方式在本章的下一节中讲解)。

当前的DbContext

在实体的构造函数的参数中,将当前的DbContext作为参数。

示例代码:

public class Order { private NorthwindContext _northwindContext; public Order(NorthwindContext northwindContext) { this._northwindContext = northwindContext; } public int OrderID { get; set; } public string CustomerID { get; set; } private ICollection<OrderDetail> _orderDetails; [NotMapped] public ICollection<OrderDetail> OrderDetails { get { if (this._orderDetails == null) this._orderDetails = this._northwindContext.Set<OrderDetail>() .Where(item => item.OrderID == this.OrderID).ToList(); return this._orderDetails; } set => _orderDetails = value; } } 当前实体的元数据

在实体的构造函数的参数中,将当前实体的的IEntityType作为参数。

示例代码:

public class Order { private IEntityType _entityType; public Order(IEntityType entityType) { this._entityType = entityType; } public int OrderID { get; set; } public string CustomerID { get; set; } [NotMapped] public IEntityType EntityType { get { return this._entityType; } } }

如果实体存在多个构造函数,框架会选择参数个数最多的那个;如果按参数个数优先选择后,依然存在多个构造函数,则会抛异常。在当前体验版本中,暂时无法直接支持自定义参数,不过在下一个发布版本中,会提供解决方案。

懒加载

懒加载是一个非常有争论的功能激烈争论的功能。虽然有些人认为它会导致性能下降或出现意想不到的Bug,但是不影响有些开发人员依旧喜欢它。EF Core 2.1 Preview 1增加了懒加载,提供了两种实现方式。

使用ILazyLoader接口实现懒加载

在实体的构造函数中传入ILazyLoader,在导航属性中,使用接口的Load方法,实现导航属性的数据加载。

示例代码:

public class Order { private ILazyLoader _lazyLoader; public Order(ILazyLoader lazyLoader) { this._lazyLoader = lazyLoader; } public int OrderID { get; set; } public string CustomerID { get; set; } public DateTime? OrderDate { get; set; } private ICollection<OrderDetail> _orderDetails; public ICollection<OrderDetail> OrderDetails { get => this._lazyLoader.Load(this, ref _orderDetails); set => _orderDetails = value; } } 通过代理类实现懒加载

这种方式,需要单独安装 Microsoft.EntityFrameworkCore.Proxies Nuget 包,它通过 Castle.Core 框架来生成代理类来实现对导航属性的延迟加载。

启用懒加载需要注意以下两点:

在配置中启用懒加载;

实体类不能是封闭(sealed)类,导航属性必须是虚(virtual)属性。

这种方式,在以前的博客我已经分享过,只不过当时还没有发布,原文地址:Entity Framework Core 懒加载。

值转换

EF Core 2.1 允许您将插入数据库的值自定义转换逻辑。例如:将属性的值进行加密与解密。

示例,将插入的值进行Base64编码,在查询的时候进行Base64解码。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzfwp.html