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、第一个查询、等操作时才会初始化。如果你的模型很大,有几百几千种实体和对应关系,那么初始化操作时间可能就会比较长。
解决这个问题一般有两种方式:

  1. 提前触发初始化,比如在Startup里,或者在应用启动之后手动触发一次。
  2. 使用本次版本新增预编译功能。

这里我就只介绍第二点了。
首先,使用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的查询性能进行了巨大改进,包括:

  1. efcore 6.0 比 efcore 5.0在TechEmpower Fortunes基准测试中,得力于.net6比.net5的性能提升+ef6比ef5的性能提升+测试项优化,总体大概快了70%。
  2. ef6的AsNoTracking查询提升了31%。
  3. 查询时,堆分配时间减少了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?

添加 [DataContract] 到 Entity Framework 6.0 POCO Template

Entity Framework 6.0 Raw Sql 查看模型