日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/4 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一步步学习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跨平臺或掃描二維碼關注

總結

以上是生活随笔為你收集整理的一步步学习EF Core(2.事务与日志)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。