一步步学习EF Core(2.事务与日志)

前言

上节我们留了一个问题,为什么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 = 2 });_context.ClassTable.Add(new ClassTable {
ClassName = "BBBBB", ClassLevel = 2 });_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.RelationalCommandBuilderFactoryif (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.

相关文章:

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

原文地址:http://www.cnblogs.com/GuZhenYin/p/6862505.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/325559.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个思维习惯,让你成为架构师

转载自 一个思维习惯&#xff0c;让你成为架构师 程序员的迷茫不仅仅是面对技术繁杂的无力感&#xff0c;更重要的是因为长期埋没于软件 世界的浩大的分工体系中&#xff0c;无法看清从业务到软件架构的价值链条&#xff0c;无法清楚定位自 己在分工体系的位置&#xff0c;处…

学习心得——高婕

18级青鸟1班高婕在这里和大家谈谈我学习的心得体会。我认为&#xff0c;要把学习当作是一种乐趣&#xff0c;不要当作一种负担。作为一名学生&#xff0c;我们要尊重老师的辛勤劳动&#xff0c;认真听好每一节课。其实在这里学习编程很简单&#xff0c;跟着老师的步调走&#x…

JS中对象的总结

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>03_对象</title> </head> <body> <!-- 1. 什么是对象?* 代表现实中的某个事物, 是该事物在编程中的抽象* 多个数据的集合体(封装…

AndroidOkhttp3上传单个文件

implementation com.squareup.okhttp3:okhttp:3.10.0implementation com.squareup.okio:okio:1.12.0忽略https请求&#xff1a; res->xml->network_security_config.xml <?xml version"1.0" encoding"utf-8"?> <network-security-config…

Visual Studio 2017 针对移动开发的新特性介绍

Visual Studio是世界上最好的IDE之一&#xff0c;如果是 .NET世界&#xff0c;那就没有之一了(^_^)&#xff0c;而最近推出的Visual Studio 2017在移动平台方面更是加强了这一点。这个版本包含了一些非常棒的功能&#xff0c;包括实时单元测试、新的重构、代码提示、C&#xff…

一文读懂什么是Java中的自动拆装箱

转载自 一文读懂什么是Java中的自动拆装箱 本文主要介绍Java中的自动拆箱与自动装箱的有关知识。 一、基本数据类型 基本类型&#xff0c;或者叫做内置类型&#xff0c;是Java中不同于类(Class)的特殊类型。它们是我们编程中使用最频繁的类型。 Java是一种强类型语言&am…

学习心得——张坤鹏

19级青鸟3班张坤鹏学习编程是很累的&#xff0c;需要不断地实践和探索&#xff1b;我的姑父就是学习计算机的&#xff0c;他说你选择了这个行业会很累&#xff0c;但只要你能入门&#xff0c;你就会了解到它的乐趣&#xff1b;我曾经见我姑父做一个项目&#xff0c;除了吃饭&am…

JS中的函数

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>04_函数</title> </head> <body> <!-- 1. 什么是函数?* 具有特定功能的n条语句的封装体* 只有函数是可执行的, 其它类型的数据是…

Android10创建文件Permission denied 失败

Android 10 创建文件一直报错&#xff1a;Permission denied&#xff1b; 原来 Android 10 改变了文件的存储方式 可以在Androidmainfest 里面的application添加 android:requestLegacyExternalStorage"true"

Microsoft发布.NET架构指南草案

微软开发部和Visual Studio产品团队提供了四份应用程序架构指南草案。这些草案涉及四个领域&#xff1a;微服务和Docker、ASP.NET Web应用程序、Azure云部署及Xamarin移动应用程序。每份指南包含一套符合相应主题的文档。微软希望可以获得整个社区对这些文档草案的反馈。 微服…

什么是线程安全,你真的了解吗

转载自 什么是线程安全&#xff0c;你真的了解吗 记得今年3月份刚来杭州面试的时候&#xff0c;有一家公司的技术总监问了我这样一个问题&#xff0c;说你给我说说有哪些线程安全的类&#xff0c;我心里一想&#xff0c;呵呵&#xff0c;这我早都背好了&#xff0c;稀里哗啦说…

学习心得——徐龙翥

19级青鸟3班 徐龙翥千里之行始于足下&#xff0c;不要认为html全是代码就认为学习起来特别艰难&#xff0c;如果你仔细观察的话就会发现&#xff0c;其实单词并没有多少&#xff0c;语法也并不复杂&#xff0c;只要做到上课认真听讲&#xff0c;课前预习以及课后复习&#xff0…

JS中的回调函数

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>05_回调函数</title> </head> <body> <button id"btn">测试点击事件</button> <!-- 1. 什么函数才是回调…

基于DotNet Core的RPC框架(一) DotBPE.RPC快速开始

0x00 简介 DotBPE.RPC是一款基于dotnet core编写的RPC框架&#xff0c;而它的爸爸DotBPE&#xff0c;目标是实现一个开箱即用的微服务框架&#xff0c;但是它还差点意思&#xff0c;还仅仅在构思和尝试的阶段。但不管怎么说RPC是微服务的基础&#xff0c;先来讲讲RPC的实现吧。…

android sharedpreferences工具类

package com.xt.deeptest5g.Utils;import android.content.Context; import android.content.SharedPreferences;/*** author : ZJS* e-mail : * date : 20-7-30下午7:46* desc : 用户账户信息保存工具类* version : 1.0*/ public class SharedPreferencesUtils {/*** 保存…

学习心得——刘文瑞

19级青鸟3班 刘文瑞以前因为经常玩游戏的原因&#xff0c;导致我对软件特别感兴趣&#xff0c;但是由于学习到的东西不多&#xff0c;经常是在玩游戏&#xff0c;真正能运用到计算机上的知识实在是少的可伶。像是代码之类的东西&#xff0c;以前只是听说过&#xff0c;但是一点…

教你如何定位及优化SQL语句的性能问题

转载自 教你如何定位及优化SQL语句的性能问题 在现如今的软件开发中&#xff0c;关系型数据库是做数据存储最重要的工具。无论是Oracale还是Mysql&#xff0c;都是需要通过SQL语句来和数据库进行交互的&#xff0c;这种交互我们通常称之为CRUD。在CRUD操作中&#xff0c;最最…

JS中的(IIFE)(立即调用函数)

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>06_IIEF</title> </head> <body> <!-- 1. 理解* 全称: Immediately-Invoked Function Expression 立即调用函数表达式* 别名: 匿…

SQL Server on Ubuntu——Ubuntu上的SQL Server(全截图)

本文从零开始一步一步介绍如何在Ubuntu上搭建SQL Server 2017&#xff0c;包括安装系统、安装SQL等相关步骤和方法&#xff08;仅供测试学习之用&#xff0c;基础篇&#xff09;。 一&#xff0e; 创建Ubuntu系统&#xff08;Create Ubuntu System&#xff09; 1. 前提准…

dp与px相互转换

package com.xt.deeptest5g.Utils;import android.content.res.Resources;/*** author : ZJS* e-mail : 15574564770163.com* date : 20-7-30下午9:02* desc : dp与px相互转换* version : 1.0*/ public class DensityUtil {public float density;public DensityUtil() {den…