开发者社区> 优惠活动> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

C# 数据操作系列 - 8. EF Core的增删改查

简介:
+关注继续查看

C# 数据操作系列 - 8. EF Core的增删改查

0.前言
到目前为止,我们看了一下如何声明EF Core的初步使用,也整体的看了下EF Core的映射关系配置以及导航属性的配置。

这一篇,我带大家分享一下,我在工作中需要的EF Core的用法。

  1. 初始化
    在实际开发中,一般都是先设计好数据表再进行开发,所以很少用到EF Core的数据迁移功能。所以EF Core的初始化,一般也指的是EF Core上下文初始化。

1.1 连接字符串
我们通过前面的文章知道,EF Core在上下文初始化的时候,都需要一个链接字符串。如果在不考虑后续变更或者上下文的复用性,可以直接在自定义Context里重写OnConfiguring方法中定义。

如果需要后续变更,那么就需要在创建自定义EF Core 上下文类的时候,为之添加一个连接字符串的属性或者字段,以方便初始化的时候指定。实例:

public class DefaultContext : DbContext
{

private string Connection { get; set; } = "Data Source=./blogging1.db";
public DefaultContext(string connection)
{
    Connection = connection;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
    => options.UseSqlite(Connection);

}
这样一来,我们在后续使用的时候,就可以指定连接字符串了。当然了,如果有小伙伴有更好的方法也可以分享出来呀。

1.2 配置文件的加载或者实体对象的托管
如果我们不使用配置文件的话,就必须在EF Core的上下文类里添加一个类型是DbSet的属性。继续延续上面的实例:

public class SingleModel
{

public int Id { get; set; }
public int TargetId { get; set; }
public SingleTargetModel SingleTarget { get; set; }

}

public class SingleTargetModel
{

public int Id { get; set; }
public SingleModel Single { get; set; }

}
public class DefaultContext : DbContext
{

// 其余代码参见 1.1  DefaultContext
public DbSet<SingleModel> Singles { get; set; }
public DbSet<SingleTargetModel> Targets { get; set; }

}
以上也就是这一小节标题中的实体对象的托管。我没找到EF Core官方文档中对于这种方式的称呼,所以我就悄悄的抢注了一下为托管。

如果我们使用Config类(也就是 《C# 数据操作系列 - 7. EF Core 导航属性配置》中介绍的配置类)的话,需要在EF Core中应用配置,具体是:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{

modelBuilder.ApplyConfiguration(new SingleModelConfig());
modelBuilder.ApplyConfiguration(new SingleTargeModelConfig());

}
在使用的时候,可以直接:

var context = new DefaultContext("Data Source=demo.db");
var t1 = context.Set().First();
即使用DbContext.Set,可以获取到一个数据加载集,当然也可以结合实体类的托管来一起使用。

那么为什么,我推荐使用配置类加载吗?

因为在实际开发中,一个完整的程序或者网站实体类都会大于10,而这些如果使用属性的形式会非常多,不利于实际开发。而且,EF Core可以通过 Assembly 方式整体加载配置文件。再者,为了保证ORM中的O不受其他因素的影响。也就是说,如果使用注解形式配置映射关系,那么势必会造成影响。

当然了,使用配置文件必然会导致项目的类增多,而且大量的重复类可能会出现。当然了,如果考虑到这个问题的话,可以试试写一个项目代码生成器哦,专门用来处理这些差不多的类。

咳咳,总而言之,使用配置文件利大于弊,所以我推荐使用配置文件对关系进行配置。

  1. 数据变化
    换句话说,嗯,也就是增删改。在数据增删这两方面,EF Core没有太多需要注意的地方。不过如果有导航属性的话,在新增的时候,EF Core会自动检索导航属性的另一端是否需要新增到数据库中,如果需要新增的话,EF Core会自动标记为新增的。

而删除,如果在配置导航属性时,没有设置级联删除,删除当前元素,如果另一端的外键是可空类型的,并不会删除导航属性另一端的元素只会设置外键指向为NULL,如果另一端外键是不可空的,那么就会同时删除。如果需要修改,可以使用以下方法修改,在配置导航属性的时候:

OnDelete(DeleteBehavior.Cascade);
对于可为NULL的外键来说,枚举DeleteBehavior的值起以下作用:

行为名称 对内存中的依赖项/子项的影响 对数据库中的依赖项/子项的影响
Cascade 删除实体 删除实体
ClientSetNull(默认) 外键属性设置为 null None
SetNull 外键属性设置为 null 外键属性设置为 null
Restrict None None
而对于不可为NULL的外键来说,枚举DeleteBehavior的值起以下作用:

行为名称 对内存中的依赖项/子项的影响 对数据库中的依赖项/子项的影响
Cascade(默认) 删除实体 删除实体
ClientSetNull SaveChanges 引发异常 None
SetNull 引发 SaveChanges SaveChanges 引发异常
Restrict None None
而对于数据的修改,EF Core的做法是通过监控实体的ChangeTracker来实现对数据实体的状态更新。也就是说,如果你从EF Core的上下文获取了一个实体对象,对这个对象的某些值进行了修改。这时候EF Core其实已经记录了这个对象的修改。不需要我们额外的调用修改方法(因为根本没有Update方法)。

EF Core在我们调用 SaveChanges 会把缓存的所有更改(增、删、改)都推送给数据库。如果有一条数据变更因为数据库校验或者其他约束没有通过,就会报错,同时撤销所有已推送的变更并取消后续变更的推送。

从数据库的角度来看,EF Core在SaveChanges的过程中是以事务的形式推送给数据库的。如果出错,那么事务就会回滚。

所以一般情况下,EF不需要开启事务。

3.花样查询
EF Core 支持Linq查询,所以在查询的时候可以使用Linq进行。简单示例如下:

var context = new DefaultContext("Data Source=demo.db");
var results = from t in context.Set()

         select t;

当然,也可以使用方法链的形式传入一个Expression> 类型的表达式。

var results = context.Set().Where(t=>true);
看到这里了,可能会有疑问了,这明明很简单呀。是的,如果只是查询,自然简单。

那么,结合排序、分页之后呢?先来看看排序是怎么实现的吧。

在查询表达式写法中,排序应该这样的写的:

var results = from t in context.Set()

        orderby t.Id //descending 如果降序则取消注释
        select t ;

方法链的形式是:

var results = context.Set().Where(t=>true).OrderBy(t=>t.Id);
分页只能通过方法链的形式进行分页,这里提供一个分页的工具方法:

public static IQueryable Paging(IQueryable source,int pageIndex,int pageSize)
{

return source.Skip(pageSize * (pageIndex - 1)).Take(pageSize);

}
这里用到的是 Skip(int count) 表示忽略数据集的前count条记录,Take(int count)取得数据集的前count条记录。

EF Core在调用 ToList的时候,会将已调用的方法和Linq转换成SQL语句,并正式向数据库发起查询。如果出现了在Linq中调用三方方法或者自己写的工具方法的话,可能会提示不受支持。

如果使用的Linq表达式,则没关系,EF Core在遇到这种情况的时候,会把数据库里所有数据都加载到上下文中,再执行后续的查询等操作。

所以,为了高效的查询,在执行查询的时候,最好使用简单的查询条件。

  1. 后续
    EF Core整体使用已经介绍完了,当然照例是普通工程级的内容。下一篇我给大家介绍一下EF Core剩下一些边角料,嗯。如果要深挖代码的话,得以后有机会了。

数据访问系列,EF Core 篇即将到一段落。待EF Core篇完成后,将带领一起去探索 Nhibernate和Dapper,SqlSugar这三个ORM框架。

原文地址https://www.cnblogs.com/c7jie/p/12910627.html

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
大数据入门与实战-Hive操作与SQL 查询
大数据入门与实战-Hive操作与SQL 查询
42 0
如何利用.NETCore向Azure EventHubs准实时批量发送数据?
Azure事件中心的基础用法 .NET Core准实时分批向Azure事件中心发送数据,其中用到的TPL Dataflow以actor模型:提供了粗粒度的数据流和流水线任务,提高了高并发程序的健壮性。
69 0
MySQL---数据库从入门走向大神系列(二)-用Java对MySQL进行增删改查
MySQL---数据库从入门走向大神系列(二)-用Java对MySQL进行增删改查
88 0
阿里云数据湖分析-控制台支持SQL的停止操作
阿里云数据湖分析今天发布了控制台对于SQL停止操作的支持, 您提交了一个查询之后,可以点击“停止”进行终止。
429 0
MySQL优化系列(一)--库与表基本操作以及数据增删改
MySQL优化系列(一)--库与表基本操作以及数据增删改 数据库,后端开发者必学,而且现在以MySQL居多。这个系列将系统化MySQL一些高级用法。打算先讲很多人关注的使用方式(增删改查以及其优化),然后就讲数据库和表的操作(很多我们学习忽略的地方),接着就是引擎还有更高级的查询等等。
1343 0
+关注
优惠活动
阿里云代金码,领券优惠bieryun.com
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载