前言

上节我们留了一个问题,为什么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. 安全超文本传输协议(HTTPS)详解

    一.概念与摘要 HTTPS (Secure Hypertext Transfer Protocol)安全超文本传输协议,是一个安全通信通道,它基于HTTP开发用于在客户计算机和服务器之间交换信息.它使 ...

  2. 云计算+SaaS+业务开发平台=JSAAS云平台

    我关注Google的代码托管.Open API,我也关注Oracle会把MYSQL怎么样云数据库化,我也虚拟化技术多实例化独立的数据库,我也关注facebook的平台插件应用架构,我也关注salesf ...

  3. 老李分享:loadrunner操作mysql数据库

    老李分享:loadrunner操作mysql数据库        在poptest测试开发工程师就业培训的课程中,针对一套商业系统进行性能测试,目标是mysql后台数据库的负载能力,在这里我把测试代码 ...

  4. 查看mac上的隐藏文件

    打开终端敲入(最好是复制),这样就可以隐藏隐藏文件: defaults write com.apple.finder AppleShowAllFiles -boolean false ; killal ...

  5. Android Google AdMob 广告接入示例

    Android Google AdMob 广告接入示例 [TOC] 首先请大家放心,虽然 Google搜索等服务被qiang了,但是 广告服务国内还是可以用的,真是普天同庆啊~~~噗! 其实这篇文章也 ...

  6. opencv构建高斯卷积核

    关于高斯核函数可以参见阮一峰老师的日志:高斯模糊的算法 如何使用高斯核进行高斯模糊可以参见我的另一篇日志:opencv构建自定义卷积 Mat Gaussian_kernal(int kernel_si ...

  7. Spring配置数据源的几种方法

    一:数据源的配置1.通过JNDI配置数据源    1.在tomcat context.xml中配置数据源        <Resource name="jdbc/ds" au ...

  8. gulp基于seaJs模块化项目打包实践【原创】

    公司还一直在延续使用jq+seajs的技术栈,所以只能基于现在的技术栈进行静态文件打包,而众所周知seajs的打包比较"偏门",在查了不少的文档和技术分享后终于琢磨出了自己的打包策 ...

  9. MyBatis注解配置动态SQL

    MySQL创建表 DROP TABLE IF EXISTS `tb_employee`; CREATE TABLE `tb_employee` ( `id` int(11) NOT NULL AUTO ...

  10. phpcms课堂笔记

    获取父分类下面的子分类 {loop subcat(77) $k $v}{php $subcatid[] = $k;}{/loop}<?php $subcatid = implode(',', $ ...