Entity Framework Core 6.0 中的新功能介绍
Posted JimCarter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Entity Framework Core 6.0 中的新功能介绍相关的知识,希望对你有一定的参考价值。
文章目录
EF Core本次升级了不少东西,大概看了一下,对一些自我感觉比较常用的内容做了一些罗列,未尽之处还请阅读官方完整文档:https://docs.microsoft.com/zh-cn/ef/core/what-is-new/ef-core-6.0/whatsnew
一、 新功能
1. 支持临时表(时态表)
支持创建和使用时态表(SQL Server 2016新增的功能),现在已经支持了下述几个功能:
- 使用迁移创建时态表
- 再次使用迁移将现有表转换为时态表
- 查询历史数据
- 从过去某个时间点还原数据
如果在项目里有使用时态表,可转到详情继续阅读。
2. 预编译的模型
我们知道应用在首次使用DbContext时会花费一定的时间来初始化ef模型,仅创建DbContext实例不会初始化ef模型,只有当执行Add、第一个查询、等操作时才会初始化。如果你的模型很大,有几百几千种实体和对应关系,那么初始化操作时间可能就会比较长。
解决这个问题一般有两种方式:
- 提前触发初始化,比如在Startup里,或者在应用启动之后手动触发一次。
- 使用本次版本新增预编译功能。
这里我就只介绍第二点了。
首先,使用dotnet ef dbcontext optimize
命令生成预编译的模型(--output-dir
和 --namespace
参数指定输出目录和模型的命名空间)。此命令会返回一段提示信息,提示信息里会告诉你怎么用。
PS C:\\dotnet\\efdocs\\samples\\core\\Miscellaneous\\CompiledModels> dotnet ef dbcontext optimize --output-dir MyCompiledModels --namespace MyCompiledModels
Build started...
Build succeeded.
Successfully generated a compiled model, to use it call 'options.UseModel(MyCompiledModels.BlogsContextModel.Instance)'. Run this command again when the model is modified.
然后,将上述提示的代码配置到到dbcontext上:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseModel(MyCompiledModels.BlogsContextModel.Instance)
.UseSqlite(@"Data Source=test.db");
最后,预编译的模型也有一些不足:
- 不支持全局查询筛选器。
- 不支持延迟加载和更改跟踪代理。
- 不支持自定义 IModelCacheKeyFactory 实现。 但是,可以编译多个模型,并根据需要加载相应的模型。
- 在模型定义或配置更改时,必须重新生成模型来手动同步模型。
由于这些不足,只应在 EF Core 启动时间太慢时使用已编译的模型。 编译小型模型通常不太值得使用已编译的模型。
预编译的模型到底提升了多少性能?
微软给出来一个示例代码,包含 449 种实体类型、6390 个属性和 720 种关系。 这是一个中等大小的模型。 使用 BenchmarkDotNet 进行度量,首次查询的平均时间为 1.02 秒。 在相同的硬件上,使用已编译的模型可将这一时间缩短到 117 毫秒。 随着模型大小的增加,会保持类似这样相对稳定的 8 到 10 倍的改进。
3. 性能提升
对ef的查询性能进行了巨大改进,包括:
- efcore 6.0 比 efcore 5.0在TechEmpower Fortunes基准测试中,得力于.net6比.net5的性能提升+ef6比ef5的性能提升+测试项优化,总体大概快了70%。
- ef6的AsNoTracking查询提升了31%。
- 查询时,堆分配时间减少了43%。
经过上述改进之后Dapper和ef的差距从55%缩减到了5%以下。
详见这里
4. 一些对Cosmos的改进支持
如果用到了cosmos db可以阅读官方博文
5. 支持可空引用类型
现在支持把public string? Description get; set;
数据库设置为可空类型。
6. DbFirst模式支持将数据库里注释添加到实体属性上
public partial class Blog
/// <summary>
/// 这里是数据库里的字段注释
/// </summary>
[Key]
public int Id get; set;
7. [PrecisionAttribute],用来配置数据库列的精度
可以使用PrecisionAttribute
来配置数据库列的精度和小数位的个数:
public class Product
public int Id get; set;
//精度为10, 2位小数
[Precision(precision: 10, scale: 2)]
public decimal Price get; set;
8. [EntityTypeConfiguration]特性
IEntityTypeConfiguration<TEntity>
允许将每个实体类型的 ModelBuilder
配置包含在其各自的配置类中。如:
public class BookConfiguration : IEntityTypeConfiguration<Book>
public void Configure(EntityTypeBuilder<Book> builder)
builder
.Property(e => e.Isbn)
.IsUnicode(false)
.HasMaxLength(22);
然后实例化并进行配置:
protected override void OnModelCreating(ModelBuilder modelBuilder)
new BookConfiguration().Configure(modelBuilder.Entity<Book>());
最后,添加特性:
[EntityTypeConfiguration(typeof(BookConfiguration))]
public class Book
public int Id get; set;
public string Title get; set;
public string Isbn get; set;
以后每当模型中包含 Book 实体类型时,EF Core 都将使用指定的 IEntityTypeConfiguration
实现
9. 多对多实体关系配置简化
比如如下的配置,会产生一个中间表:
modelBuilder.Entity<Cat>()
.HasMany(e => e.Humans)
.WithMany(e => e.Cats);
从ef6开始,你可以使用UsingEntity
简化手动指定实体的配置:
modelBuilder.Entity<Cat>()
.HasMany(e => e.Humans)
.WithMany(e => e.Cats)
.UsingEntity<CatHuman>();
也可以进行完整配置:
modelBuilder.Entity<Cat>()
.HasMany(e => e.Humans)
.WithMany(e => e.Cats)
.UsingEntity<CatHuman>(
e => e.HasOne<Human>().WithMany().HasForeignKey(e => e.CatsId),
e => e.HasOne<Cat>().WithMany().HasForeignKey(e => e.HumansId),
e => e.HasKey(e => new e.CatsId, e.HumansId ));
二、中断性变更
如果生产项目有升级ef版本的需求,一定要阅读:
https://docs.microsoft.com/zh-cn/ef/core/what-is-new/ef-core-6.0/breaking-changes
参考:
https://docs.microsoft.com/zh-cn/ef/core/what-is-new/ef-core-6.0/whatsnew
https://docs.microsoft.com/zh-cn/ef/core/what-is-new/ef-core-6.0/breaking-changes
以上是关于Entity Framework Core 6.0 中的新功能介绍的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework Core 6.0 中的新功能介绍
Entity Framework Core 6.0 中的新功能介绍
Entity Framework Core 6.0 中的新功能介绍
如何在 .Net Core 6.0 中结合 CosmosDB、Entity Framework 和 OData?