EF Core知识点

catch (DbUpdateConcurrencyException ex)
	{
        //通过DbUpdateConcurrencyException类的Entries属性获取并发修改冲突的EntityEntry
   		 //并通过EntityEntry类中的GetDatabaseValuesAsync获取当前数据库的值
		var entry = ex.Entries.First();
		var dbValues = await entry.GetDatabaseValuesAsync();
		string newOwner = dbValues.GetValue<string>(nameof(House.Owner));
		Console.WriteLine($"并发冲突,被{newOwner}提前抢走了");
	}
IEnumerableIQueryable

对普通集合使用where等方法查询出来的返回值为IEnumerable类型

但是对DbSet使用用where等方法出查询出来的返回值为IQueryable类型

IQueryable继承自IEnumerable,IQueryable是延迟执行,能减少内存的压力,使用IQueryable是把where方法转换成SQL语句,使得可以在数据库中进行过滤查询。

*判断是否为立即执行方法:*如果返回值类型是IQueryable则是非立即执行方法

立即执行方法非立即执行方法
遍历IQueryable方法Where
ToArrayGroupBy
ToListOrderBy
MinInclude
MaxSkip
CountTake

-------------------------------------------------------------------------------------------------------------------------------

原理

ADO.NET中的DataReader中是分批从数据库中读取数据,而DataTable则是一次性读取数据

在遍历IQueryable时,是使用DataReader的方式读取数据,这样会一直占用一个数据库的连接。如果使用ToArray等方法,则使用了DataTable方式

在使用时如果返回的是IQueryable,请注意上下文的生效周期

使用dbCtx.Database.ExecuteSqlInterpolated或者异步的ctx.Database.ExecuteSqlInterpolatedAsync方法执行SQL语句

-----------------------------------------------------------------------------

新特性

1、增加了实体类的跟踪状态

2、增加了全局查询筛选器 典型场景应用:伪删除

例如在Book类中增加一个bool属性值IsDeleted,标记是否被删除

在配置类中增加builder.HasQueryFilter(b=>b.IsDeleted==false),这样在对Book实体类的查询都会自动加上b.IsDeleted==false这个筛选器

如果需要查询被删除的数据,可以使用IgnoreQueryFilters来临时忽略过滤器

ctx.Books.IgnoreQueryFilters().Where(b=>b.Title.Contains("a"))

3、配置类

实现一个配置类,用来说明实体类和数据库表是怎么映射的,该配置类要实现IEnityTypeConfiguration接口

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

class BookEntityConfig : IEntityTypeConfiguration<Book>  //指定是对那个类进行配置
{
    public void Configure(EntityTypeBuilder<Book> builder) //实现接口
    {
        builder.ToTable("T_Books"); //实体对象在数据库中表的名字是“T_Books”
        //没有详细设置每个属性在数据库中的列明和数据类型
        //会默认吧属性名字作为列明,并根据属性类型来推断数据库中的数据类型
        
        //可以根据需要修改实体类的配置,进而修改数据库的表
        //HasMaxLength(50):最大长度为50 IsRequired():不可为空
        builder.Property(e => e.Title).HasMaxLength(50).IsRequired();
        builder.Property(e => e.AuthorName).HasMaxLength(20).IsRequired();
    }
}

悲观并发控制

使用事务+锁

using var tx = await ctx.Database.BeginTransactionAsync();
//for update创建用于更新的锁,如果其他用户也使用for update查询id=1的数据,则查询被挂起,这是mysql的语法
var h1 = await ctx.Houses.FromSqlInterpolated($"select * from T_Houses where Id=1 for update")
	.SingleAsync();

if (string.IsNullOrEmpty(h1.Owner))
{

}
else
{

}
await tx.CommitAsync();//提交事务
乐观并发控制

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

执行update hourse set Owner=新值 where Id=1 and Owner = 旧值,如果其他人更改了Owner则where语句就是false,此时SaveChanges方法会抛出DbUpdateConcurrencyException

class HouseConfig : IEntityTypeConfiguration<House>
{
	public void Configure(EntityTypeBuilder<House> builder)
	{
		builder.ToTable("T_Houses");
        //在配置类中使用IsConcurrencyToken把Owner列设置为并发并令牌属性
		builder.Property(h => h.Owner).IsConcurrencyToken();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值