谈谈EntityFramework Core中的异步编程及约定

约定

由于 Entity Framwork 有一定的约束条件,你只需要按规则编写很少的代码就能够创建一个完整的数据库。

  • DbSet 类型的属性用作表名。 如果实体未被 DbSet 属性引用,实体类名称用作表名称。

  • 使用实体属性名作为列名

  • 以 ID 或 classnameID 命名的实体属性被视为主键属性

  • 如果属性名为 <导航属性名><主键属性名>(例如,StudentID 对应 Student 导航属性,因为 Student 实体的主键是 ID),其将被解释为外键属性。 此外还可以将外键属性仅命名为 <主键属性名>(例如 EnrollmentID,因为 Enrollment 实体的主键为 EnrollmentID) 。

为了更好理解,我们看如下例子,建立一个Students实体

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
    public class Student
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }

        public ICollection<Enrollment> Enrollments { get; set; }
    }
}

其中,实体属性ID,Lastanme等就是列名,ID 属性将成为对应于此类的数据库表中的主键。 默认情况下,EF 将会将名为 ID 或 classnameID 的属性解析为主键。

Enrollments 属性是导航属性。 导航属性中包含与此实体相关的其他实体。 在这个案例下,Student entity 中的 Enrollments 属性会保留所有与 Student 实体相关的 Enrollment。 换而言之,如果在数据库中有两行描述同一个学生的修读情况 (两行的 StudentID 值相同,而且 StudentID 作为外键和某位学生的主键值相同), Student 实体的 Enrollments 导航属性将包含那两个 Enrollment 实体。

如果导航属性可以具有多个实体 (如多对多或一对多关系),那么导航属性的类型必须是可以添加、 删除和更新条目的容器,如 ICollection<T>。 你可以指定 ICollection<T> 或实现该接口类型,如 List<T> 或 HashSet<T>。 如果指定 ICollection<T>,EF在默认情况下创建 HashSet<T> 集合。

数据库中的情况;

Course-Enrollment-Student 数据模型关系图

EF Core会自动将标识出导航属性

异步代码

异步编程是 ASP.NET Core 和 EF Core 的默认模式。

Web 服务器的可用线程是有限的,而在高负载情况下的可能所有线程都被占用。 当发生这种情况的时候,服务器就无法处理新请求,直到线程被释放。 使用同步代码时,可能会出现多个线程被占用但不能执行任何操作的情况,因为它们正在等待 I/O 完成。 使用异步代码时,当进程正在等待 I/O 完成,服务器可以将其线程释放用于处理其他请求。 因此,异步代码使得服务器更有效地使用资源,并且该服务器可以无延迟地处理更多流量。

异步代码在运行时,会引入的少量开销,在低流量时对性能的影响可以忽略不计,但在针对高流量情况下潜在的性能提升是可观的。

在以下代码中,async 关键字、Task<T> 返回值、await 关键字和 ToListAsync 方法让代码异步执行。

public async Task<IActionResult> Index()
{
    return View(await _context.Students.ToListAsync());
}
  • async 关键字用于告知编译器该方法主体将生成回调并自动创建 Task<IActionResult> 返回对象。

  • 返回类型 Task<IActionResult> 表示正在进行的工作返回的结果为 IActionResult 类型。

  • await 关键字会使得编译器将方法拆分为两个部分。 第一部分是以异步方式结束已启动的操作。 第二部分是当操作完成时注入调用回调方法的地方。

  • ToListAsync 是 ToList 方法的的异步扩展版本。

使用 Entity Framework 编写异步代码时的一些注意事项:

  • 只有导致查询或发送数据库命令的语句才能以异步方式执行。 包括 ToListAsync, SingleOrDefaultAsync,和 SaveChangesAsync。 不包括只需更改 IQueryable 的语句,如 var students = context.Students.Where(s => s.LastName == "Davolio")。一下只返回有一个view,不需要异步方式。

  •  public ActionResult Create()
            {
                var newModel = new AlbumCreateViewModel();
                return View(newModel);
            }

     

  • EF 上下文是线程不安全的: 请勿尝试并行执行多个操作。 当调用异步 EF 方法时,始终使用 await 关键字。

  • 如果你想要利用异步代码的性能优势,请确保你所使用的任何库和包在它们调用导致 Entity Framework 数据库查询方法时也使用异步。

有关在 .NET 异步编程的详细信息,请参阅 异步概述

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值