EF Core基础笔记

EF Core基础

最近又细看了EF,再次详细做个总结,常规用法和一点点高级用法,应该可以解决百分之就是的问题

EFCore是什么

EFCore是微软自己的ORM框架,类比JAVA的JDBC。就是为了程序员不用操作复杂的sql,可以通过简单的操作完成对数据库的增删改查。

使用

EF使用首先写上下文类,继承DbContext,重写OnConfiguringOnModelCreating,写DbSet属性

OnConfiguring

连接字符串

OnModelCreating

包括字段类型限制和导航属性等

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
}

CRUD

实体类配置

EF Core采用了“约定大于配置”的设计原则,也就是说EF Core会默认按照约定根据实体类以及DbContext的定义来实现和数据库表的映射配置,除非用户显式地指定了配置规则。

配置类

使用:

  • 配置类继承 IEntityTypeConfiguration
1  class BookEntityConfig : IEntityTypeConfiguration<Book>
2  {
3      public void Configure(EntityTypeBuilder<Book> builder)
4      {
5          builder.ToTable("T_Books");
6          builder.Property(e => e.Title).HasMaxLength(50).IsRequired();
7          builder.Property(e => e.AuthorName).HasMaxLength(20).IsRequired();
8      }
9  }

Data Annotation配置

直接在实体类的属性上加注解

Fluent API配置

如上builder.Property(e => e.Title).HasMaxLength(50).IsRequired();这种编写

注意

  • 推荐Fluent API配置
  • 两种配置都用,Fluent API配置优先级高

关系配置

一对多、一对一、多对多

EF Core中实体类之间关系的配置采用如下的模式:HasOne(Teacher).WithMany(Student);一个老师有多个学生

关联数据的获取

Include,在使用关联表时需要使用,否则关联表的字段为null

关系的外键属性的配置

在关系配置中通过HasForeignKey()指定这个属性为外键可以不使用Include

单项导航属性

有时候我们不方便声明双向导航。比如在大部分系统中,基础的“用户”实体类会被非常多的其他实体类引用,这种单向导航属性的配置其实很简单,只要在WithMany方法中不指定属性即可

数据迁移

不建议使用,只有在数据库已经建立好,使用scaffold 命令反向工程建立实体类,建立完成还需要一定修改

迁移文件

  • XXX.cs:记录的是和具体数据库无关的抽象模型
  • XXX.Designer.cs:记录的是和具体数据库相关的代码

查看EFCore生成的SQL语句

我们只要在上下文的OnConfiguring方法中调用optionsBuilder类的LogTo方法,传递一个参数为String的委托即可。当相关日志输出的时候,对应的委托就会被执行

原理

IQueryable与IEnumerable

Enumerable类中定义的供普通集合用的Where等方法都是“客户端评估”,Queryable中定义的Where方法都是“服务的评估”

总结:
在使用EF Core的时候,能一次性筛选出的数据尽量都一条sql搞定,而不是取出再筛选,也就是尽量使用“服务端评估”

例子:
新手(其实是我)在操作多个模糊查询时,会用foreach查询多次,实际完全可以使用ContainLINQ的方法一次性取

IQueryable的延迟执行

对于IQueryable接口,调用“非立即执行”方法的时候不会执行查询,而调用“立即执行”方法的时候则会立即执行查询。

好处:

可以重复使用IQueryable的查询

判断方法:
一个方法是否是立即执行方法的简单方式是:一个方法的返回值类型如果是IQueryable类型,这个方法一般就是非立即执行方法,否则这个方法就是立即执行方法。

注:IQueryable是一个待查询的逻辑,因此它是可以被重复使用的

IQueryable的底层运行

IQueryable是用类似DataReader的方式读取查询结果的。DataReader会分批从数据库服务器读取数据。
优点是客户端内存占用小,缺点是如果遍历读取数据并进行处理的过程缓慢的话,会导致程序占用数据库连接的时间较长,从而降低数据库服务器的并发连接能力。因此,在遍历IQueryable的过程中,它需要占用一个数据库连接。

EF优化

AsNoTracking

如果开发人员能够确认通过上下文查询出来的对象只是用来展示,不会发生状态改变,那么可以使用AsNoTracking方法告诉IQueryable在查询的时候“禁用跟踪”

1  Book[] books = ctx.Books.AsNoTracking().Take(3).ToArray();
2  Book b1 = books[0];
3  b1.Title = "abc";
4  EntityEntry entry1 = ctx.Entry(b1);
5  Console.WriteLine(entry1.State);

上面代码的执行结果是“Detached”,也就说使用AsNoTracking查询出来的实体类是不被上下文跟踪的。

实体类状态跟踪

EF使用快照的方法跟踪实体的变化,也就是复制一份快照,当save的时候会查看该状态来判断是否更改数据,ctx.Entry(b1).State查看该记录的状态

并发控制

EF Core内置了使用并发令牌列实现的乐观并发控制,并发令牌列通常就是被并发操作影响的列。

例子:

我们可以把Owner列用作并发令牌列。在更新Owner列的时候,我们把Owner列更新前的值也放入Update语句的条件中,SQL语句如下:Update T_Houses set Owner=新值where Id=1 and Owner=旧值。

使用:

EF Core中,我们只要把被并发修改的属性使用IsConcurrencyToken设置为并发令牌即可。

表达式树

表达式树(expression tree)是用树形数据结构来表示代码逻辑运算的技术,它让我们可以在运行时访问逻辑运算的结构。表达式树在.NET中对应Expression <> 类型。

Tip:华而不实,很多都可以用LINQ来代替,不推荐使用,不便于更新迭代。一般只有在编写不特定于某个实体类的通用框架的时候,由于无法在编译期确定要操作的类名、属性等,才需要编写动态构建表达式树的代码,否则为了提高代码的可读性和可维护性,我们要尽量避免动态构建表达式树。

通过代码动态构建表达式树

  1. 安装NuGet包ExpressionTreeToString
  2. 在代码中添加对ExpressionTreeToString命名空间的引用
  3. 我们就可以在Expression类型上调用ToString扩展方法来输出表达式树结构的字符串了
  4. ExpressionTreeToString提供的ToString(“Object notation”,“C#”)方法只是输出一个用C#语法描述表达式树的结构及每个节点的字符串,但是这个字符串并不是可以直接运行的C#代码。
  5. 我们可以用C#的using static方法来静态引入Expression类
  6. 这样上面的代码就几乎可以直接放到C#代码中编译通过了

ASP.NET Core中EF Core的使用

使用

  • context只编写OnModelCreating方法,而OnConfig编写在Program.cs
  • Program.cs中添加
    builder.Services.AddDbContext<MyDbContext>(opt=>{
        var conStr = builder.Configuration.GetConnectionString("dEFAULT");
        opt.UseMysql(conStr)
    });
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值