概述
本文都是一些比较low,比较简单的知识点
1,延迟加载(懒加载)
推迟到数据使用时加载;只有在进行ToList/ToArray/First/FirstOrDefault()
,延迟加载导航属性等访问方法时;才会加载数据
示例,使用代理来对导航属性进行延迟加载,virtual
属性进行延迟加载
1,使用Nuget安装Microsoft.EntityFrameworkCore.Proxies
2,配置model
,使用virtual
属性
public class UserInfo
{
public long Id { get; set; }
public string UserName { get; set; }
public int Age { get; set; }
/// <summary>
/// 使用虚对象延迟加载,加载时使用的是代理对象的方式,注意使用代理时;所有的导航属性都需要使用virtual
/// </summary>
public virtual List<Employee> Employees { get; set; }
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
3,修改上下文配置
/// <summary>
/// 数据库上下文
/// </summary>
public class DemoContext : DbContext
{
private readonly string _connectionString;
public DemoContext(string connectionString)
{
_connectionString = connectionString;
}
public virtual DbSet<UserInfo> UserInfo { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(_connectionString);
}
//开启延迟加载
optionsBuilder.UseLazyLoadingProxies();
}
}
示例,使用EF Core
官方的方案的延迟加载方式
1,使用Nuget安装Microsoft.EntityFrameworkCore.Abstractions
包
2,配置Model
public class UserInfo
{
private ILazyLoader LazyLoader { get; set; }
private UserInfo(ILazyLoader lazyLoader)
{
LazyLoader = lazyLoader;
}
public long Id { get; set; }
public string UserName { get; set; }
public int Age { get; set; }
private ICollection<Employee> _employees;
//可以针对特定的属性进行延迟加载
public ICollection<Employee> Employees
{
get
{
return LazyLoader?.Load(this, ref _employees);
}
set
{
_employees = value;
}
}
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
3,在上下文配置中开启optionsBuilder.UseLazyLoadingProxies();
2,延迟加载的滥用
EF Core
为了防止滥用延迟加载;需要我们配置开启延迟加载
延迟加载使用于不确定是否需要立马加载数据,或者明确知道不需要立马加载数据的场景
3,实体跟踪
EFCore
上下文在返回数据记录时,【默认】会对数据记录进行跟踪;当对数据进行更改时,SaveChanges
方法执行时会对更改进行保存
当你查询的数据不需要修改,尤其是在你查询大量数据而不进行修改时,你可以选择不跟踪,以节省开销
1,方式一:使用时,使用AsNoTracking
方法取消跟踪查找(推荐)
var query=_dbContext.UserInfo.AsNoTracking();
2,方式二:配置跟踪查询行为
//关闭
_dbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
//开启
_dbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll;
4,显示编译查询
显示编译,相较于普通查询,显示编译查询在仅在第一次调用时对EF表达式进行编译,在下一次运行时使用内存缓存的中的编译好的结果(就是sql语句)进行查询
显式编译查询提供了高可用场景,通过使用显式编译的查询可以提高查询性能
当我们的代码需要重用以前执行的查询时,EF Core将使用哈希查找并从缓存中返回已编译的查询。我们更希望直接使用编译查询绕过散列计算和高速缓存查找
适用场景(前提查询参数不变):高并发;查询量比较大
注意:当前只能返回单个数据,不支持集合
示例:
var query = EF.CompileAsyncQuery((BusinessContext context, int id) => context.UserInfo.FirstOrDefault(a => a.Id == id);
var userInfo = query(_dbContext, 1);