暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

EF Core 要点汇总

废材码农 2021-06-25
663

一、基础概念


ORM object-rational mapping

  • 对SQL语言进行封装,降低使用难度,多种SQL语言的抽象

  • 对出来的事务、连接池、迁移、种子数据等一些功能

  • 多数情况下ORM生成的SQL脚本比自己写的要好

 

EF Core 提供一个DBContext和多个Repository(DBSet)组合完成数据查询和更新操作的ORM框架。

 

DB Context ( 工作单元UnitOfWork)

一个工作单元在一个事务范围内保留所有对数据库的变更,在这个工作单元结束的时候一次性提交所有改动到数据库。

 

DB Set (Repository)

在领域层和数据映射层之间,像一个内存级别的领域对象集合。

 

二、实践


迁移工具

  • dotnet cli

  • visual studio package management

 

dotnet cli

    dotnet tool install --global dotnet-ef
    在项目内安装
      dotnet add package Microsoft.EntityFrameworkCore.Design

       

      常用命令

        添加迁移文件
        dotnet ef migrations add InitialCreate


        移除最新的迁移文件
        dotnet ef migrations remove


        列出所有迁移版本
        dotnet ef migrations list


        从空白开始生成SQL脚本
        dotnet ef migrations script


        生成指定版本到最新版本的SQL
        dotnet ef migrations script AddNewTables


        从A-B版本生成迁移SQL脚本
        dotnet ef migrations script AddNewTables AddAuditTable


        更新到数据库
        dotnet ef database update


        强制更新某个版本到数据库
        dotnet ef database update AddNew


        根据数据库生成实体工具
        dotnet ef dbcontext scaffold "server=localhost;port=3306;user=root;password=root123456;database=db" Pomelo.EntityFrameworkCore.MySql -o Models


        三、基础配置

         

        官方文档

        https://docs.microsoft.com/zh-cn/ef/core/

         

        处理并发冲突

        https://docs.microsoft.com/zh-cn/ef/core/saving/concurrency

         

        • 乐观处理:系统认为数据的更新在大多数情况下是不会产生冲突的,只在数据库更新操作提交的时候才对数据做冲突检测。

         

        增加打上标签[Timestamp] 的字段,字段类型为 byte[] ,当执行更新时,会在更新语句加上该字段的原始值去作为Where的条件,一旦原始值和数据库中的值,会产生一个异常;

         

        • 悲观处理:对数据进行操作更新时,对操作持悲观保守的态度,认为产生数据冲突的可能性很大,需要先对请求的数据加锁再进行相关操作。

         

        日志打印SQL语句配置

        "Microsoft.EntityFrameworkCore.Database.Command":"Debug"

          appsettings.json
          {
          "Logging": {
          "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information",
          "Microsoft.EntityFrameworkCore.Database.Command": "Debug"
          }
          }
          }

           

          四、关联数据加载

          https://docs.microsoft.com/zh-cn/ef/core/querying/related-data/

           

          • 预先加载  

          SQL语句会使用Left Join查询

            var project = await _dbContext.Projects.Include(p => p.Groups)
            .FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
            • 显示加载

            SQL 语句会分别去查询单个表,再合并Load到内存里

              var project = await _dbContext.Projects
              .FirstOrDefaultAsync(p => p.Id == id, cancellationToken);


              await _dbContext.Entry(project)
                       .Collection(p =>p.Groups).LoadAsync(cancellationToken);
              • 延迟加载

              当代码去调用导航属性时才会生成SQL语句去实时查询,需要配置

              参考官网:https://docs.microsoft.com/zh-cn/ef/core/querying/related-data/lazy

               

              五、数据更新


              状态

              Entity State

              • Added

              • Unchanged

              • Modified

              • Deleted

              • Detached

                    


              Property State

              • IsModified

              • CurrentValue

              • OriginValue


              不查询删除和更新

              删除前查

                var id =1
                using(var db = new EntityDbContext){
                var entity = db.dbset.FirstOrDefault(e=>e.ID == id);
                if(entity != null){
                db.dbset.Remove(entity);
                db.SaveChanges();
                }
                }

                 

                删除不查询

                  var id =1
                  using(var db = new EntityDbContext){
                  var entity = new MyEntity{ ID = id};

                  db.dbset.Attach(entity);
                  db.dbset.Remove(entity);
                  db.SaveChanges();
                  }

                   

                  不查询更新

                    var id =1
                    using(var db = new EntityDbContext){
                      var entity = new MyEntity{ ID = id};
                      
                      db.dbset.Attach(entity);
                      
                    entity.Title = "new";
                    entity.Url = "new";

                    db.SaveChanges();
                    }


                    文章转载自废材码农,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                    评论