前言

上节我们留了一个问题,为什么EF Core中,我们加载班级,数据并不会出来

其实答案很简单,~ 因为在EF Core1.1.2 中我们在EF6.0+中用到的的延迟加载功能并没有被加入,不过在EF Core 2.0中,这个功能将回归

而且这个功能是否需要被加入进去,社区也在激烈的讨论当中,有兴趣的可以去看看:

https://github.com/aspnet/EntityFramework/issues/3797

那么我们该如何加载关联的班级呢?.

直接通过Linq join当然是可以的. 我们也可以通过贪婪加载来获取,修改查询代码如下:

 public IActionResult ListView()
{
return View(_context.UserTable.Include(a=>a.Class).ToList());
}

效果如下:

下面我们开始今天的内容

事务

关于EF Core的事务,其实与EF 6.x几乎一样,代码如下:

            using (var tran = _context.Database.BeginTransaction())
{
try
{
_context.ClassTable.Add(new ClassTable { ClassName = "AAAAA", ClassLevel = });
_context.ClassTable.Add(new ClassTable { ClassName = "BBBBB", ClassLevel = });
_context.SaveChanges();
throw new Exception("模拟异常");
tran.Commit();
}
catch (Exception)
{
tran.Rollback();
// TODO: Handle failure
}
}

在异常中Rollback即可回滚,我这里的写法,其实有点无耻.

不过目的是告诉大家,要在Commit之前回滚.

不然会得到一个异常:This SqlTransaction has completed; it is no longer usable.”

下面我们来讲一下关于EF Core中的日志

日志

我们知道,在ASP.NET Core中,大量的使用了IOC的手法来注入我们所需要的类.

EF Core其实也一样,.

首先我们需要创建一个EF日志类,继承Microsoft.Extensions.Logging.ILogger

如下:

private class EFLogger : ILogger
{
private readonly string categoryName; public EFLogger(string categoryName) => this.categoryName = categoryName; public bool IsEnabled(LogLevel logLevel)
{
return true;
} public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{ Debug.WriteLine($"时间:{DateTime.Now.ToString("o")} 日志级别: {logLevel} {eventId.Id} 产生的类{this.categoryName}");
DbCommandLogData data = state as DbCommandLogData;
Debug.WriteLine($"SQL语句:{data.CommandText},\n 执行消耗时间:{data.ElapsedMilliseconds}"); } public IDisposable BeginScope<TState>(TState state)
{
return null;
}
}

我这里面的Debug.WriteLine是为了方便调试.

正常情况下当然是写入日志文件,可以用Log4Net

然后,我们创建一个空的日志类(用来过滤不需要记录的日志)如下:

        private class NullLogger : ILogger
{
public bool IsEnabled(LogLevel logLevel)
{
return false;
} public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{ } public IDisposable BeginScope<TState>(TState state)
{
return null;
}
}

然后,我们创建一个日志提供类(注入用,EF Core1.0版本注意注释),如下:

 public class MyFilteredLoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName)
{
// NOTE: 这里要注意,这是 EF Core 1.1的使用方式,如果你用的 EF Core 1.0, 就需把IRelationalCommandBuilderFactory替换成下面的类
// Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommandBuilderFactory if (categoryName == typeof(IRelationalCommandBuilderFactory).FullName)
{
return new EFLogger(categoryName);
} return new NullLogger();
}
public void Dispose()
{ }
}

然后我们到Startup.cs的Configure()方法中注入我们的日志提供类

代码如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{ loggerFactory.AddProvider(new MyFilteredLoggerProvider());
....省略
}

运行程序,得到如下调试信息:

至此,我们就完成了日志的记录工作.

那么问题来了,在Asp.NET core中,我们可以这样注入进行日志记录.

如果在别的项目(比如控制台)中,怎么办?

下面就来解决这个问题.

在非Asp.NET core的程序中,我们需要把日志提供器从上下文里注入如下:

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{ base.OnConfiguring(optionsBuilder);
LoggerFactory loggerFactory = new LoggerFactory();
loggerFactory.AddProvider(new MyFilteredLoggerProvider());
//注入
optionsBuilder.UseLoggerFactory(loggerFactory); }
写在最后

写在最后,其实在EF Core的路线图中,我们可以看到,在2.0的版本将会提供一个更简单的日志记录方式

这段话是在(Features originally considered but for which we have made no progress and are essentially postponed)之后的:

..上面翻译过来的大概意思就是:我们原来考虑会加入的功能,但是现在并没有进展,基本要推迟的特点.(..总结三个字,然并卵)

  • Simple Logging API (#1199) - We want a simple way to log the SQL being executed (like Database.Log from EF6.x). We also want a simple way to view everything being logged.
  • 嗯..翻译过来的意思就是..我们想提供一个更简单的日志记录,比如像EF6.x中的 Database.Log 这样...()

还有一个比较有趣的东西如下:

在High priority features(高度优先的功能)中还有一段话:

  • Simple command interception provides an easy way to read/write commands before/after they are sent to the database.
  • 简单的命令拦截,将提供在发送到数据库之前/之后读取/写入命令的简单方法

我觉得这个有点类似于EF6.x的IDbCommandInterceptor.

感兴趣的朋友可以去了解一下,我之前的博文也有介绍:

EntityFramework的多种记录日志方式,记录错误并分析执行时间过长原因(系列4)

好了,就说这么多.

一步步学习EF Core(2.事务与日志)的更多相关文章

  1. [转]一步步学习EF Core(2.事务与日志)

    本文转自:http://www.cnblogs.com/GuZhenYin/p/6862505.html 上节我们留了一个问题,为什么EF Core中,我们加载班级,数据并不会出来 其实答案很简单,~ ...

  2. 一步步学习EF Core(1.DBFirst)

    前言 很久没写博客了,因为真的很忙,终于空下来,打算学习一下EF Core顺便写个系列, 今天我们就来看看第一篇DBFirst. 本文环境:VS2017  Win7  .NET Core1.1     ...

  3. 一步步学习EF Core(3.EF Core2.0路线图)

    前言 这几天一直在研究EF Core的官方文档,暂时没有发现什么比较新的和EF6.x差距比较大的东西. 不过我倒是发现了EF Core的路线图更新了,下面我们就来看看 今天我们来看看最新的EF Cor ...

  4. EF Core学习Code First

    下面通过实例来学习EF Core Code First,也就是通过EF Core迁移来完成从模型生成数据库. 本实例使用EntityFrameworkCore SQLite 数据库进行介绍,大家也可以 ...

  5. EF Core 2.0中Transaction事务会对DbContext底层创建和关闭数据库连接的行为有所影响

    数据库 我们先在SQL Server数据库中建立一个Book表: CREATE TABLE [dbo].[Book]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [Cr ...

  6. [翻译 EF Core in Action 2.3] 理解EF Core数据库查询

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

  7. [翻译 EF Core in Action 2.2] 创建应用程序的数据库上下文

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

  8. EF Core in Action 中文翻译 第一部分导航

    Entityframework Core in action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Core ...

  9. [翻译 EF Core in Action 2.1] 设置一个图书销售网站的场景

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

随机推荐

  1. xlrd的使用详细介绍以及基于Excel数据参数化实例详解

    1.安装xlrd xlrd是python用于读取excel的第三方扩展包,所以在使用xlrd前,需要使用以下命令来安装xlrd.pip install xlrd 在使用这个命令之前先确定自己有没有安装 ...

  2. 玩转 SSH 目录

    在做一个新的项目的时候,需要重新搭建一个项目. 于是趁着这个机会把之前学的几个框架的搭建都写一写,整理一下,同时也可以给大家一些参考.何乐而不为叻. 在这个系列中, 我将使用 IntelJ IDEA ...

  3. ORA-00918: 未明确定义列

    ORA-00918: 未明确定义列 出现问题原因及解决办法. --正常写,结果带上表名的字段在处理后表头名称相同,在进行下一次嵌套时就会出现问题  select au.userxm,au01.user ...

  4. Linux之shell编程函数使用

    linux shell 可以用户定义函数,然后在shell脚本中可以随便调用.下面说说它的定义方法,以及调用需要注意那些事项. 原文和作者一起讨论:http://www.cnblogs.com/int ...

  5. 设计模式(二)—工厂方法模式

         凡是出现了大量的实例需要创建,而且具有共同的接口时,可以通过工厂方法模式进行创建. 一个接口: Sender public interface Sender{ public void sen ...

  6. 发散问题——Spring容器及加载

    一.前言 发散问题系列,是围绕日常工作,发散思考,提取问题,并寻求答案的一个系列.总的来说,就是将遇到的问题发散来提出更多的问题,并通过解决发散问题,从而对问题有更深入的了解,对知识有更深刻的记忆,帮 ...

  7. es6 module + webpack

    其实在之前本人就看了 es6 里面的一部分内容,当然是阮一峰大神的 ECMAScript 6 入门. 最近闲来无事又来看下,其中 Module 的语法 这章时候,用里面代码跑的时候,理所当然的报错 S ...

  8. folly教程系列之:future/promise

         attension:本文严禁转载. 一.前言 promise/future是一个非常重要的异步编程模型,它可以让我们摆脱传统的回调陷阱,从而使用更加优雅.清晰的方式进行异步编程.c++11中 ...

  9. android通过代码获取华为手机的EMUI系统版本号

    因为app中用到华为推送,但是华为推送在不同版本上是存在不同问题的,需要单独来处理. 那么最基本的问题是要获取EMUI系统的版本号. 上网翻了很多博客帖子,基本上是在获取root权限下去读取/syst ...

  10. MySQL5.7下修改root密码

    本地安装了个mysql5.7,发现修改root密码和以往有区别了,特此记录下 进入mysql  更改密码: mysql> update mysql.user set authentication ...