一步步学习EF Core(2.事务与日志)
前言
上節(jié)我們留了一個(gè)問題,為什么EF Core中,我們加載班級(jí),數(shù)據(jù)并不會(huì)出來
其實(shí)答案很簡(jiǎn)單,~ 因?yàn)樵贓F Core1.1.2 中我們?cè)?strong>EF6.0+中用到的的延遲加載功能并沒有被加入,不過在EF Core 2.0中,這個(gè)功能將回歸
而且這個(gè)功能是否需要被加入進(jìn)去,社區(qū)也在激烈的討論當(dāng)中,有興趣的可以去看看:
https://github.com/aspnet/EntityFramework/issues/3797
那么我們?cè)撊绾渭虞d關(guān)聯(lián)的班級(jí)呢?.
直接通過Linq join當(dāng)然是可以的. 我們也可以通過貪婪加載來獲取,修改查詢代碼如下:
public IActionResult ListView(){return View(_context.UserTable.Include(a=>a.Class).ToList());}
效果如下:
下面我們開始今天的內(nèi)容?
?
事務(wù)
關(guān)于EF Core的事務(wù),其實(shí)與EF 6.x幾乎一樣,代碼如下:
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即可回滾,我這里的寫法,其實(shí)有點(diǎn)無恥.
不過目的是告訴大家,要在Commit之前回滾.
不然會(huì)得到一個(gè)異常:This SqlTransaction has completed; it is no longer usable.”
?
下面我們來講一下關(guān)于EF Core中的日志
?
日志
我們知道,在ASP.NET Core中,大量的使用了IOC的手法來注入我們所需要的類.
EF Core其實(shí)也一樣,.
首先我們需要?jiǎng)?chuàng)建一個(gè)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($"時(shí)間:{DateTime.Now.ToString("o")}
日志級(jí)別: {logLevel} {eventId.Id} 產(chǎn)生的類{this.categoryName}");DbCommandLogData data = state as DbCommandLogData;Debug.WriteLine($"SQL語句:{data.CommandText},\n 執(zhí)行消耗時(shí)間:{data.ElapsedMilliseconds}");}
public IDisposable BeginScope<TState>(TState state){ return null;}}
我這里面的Debug.WriteLine是為了方便調(diào)試.
正常情況下當(dāng)然是寫入日志文件,可以用Log4Net
然后,我們創(chuàng)建一個(gè)空的日志類(用來過濾不需要記錄的日志)如下:
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;}}
然后,我們創(chuàng)建一個(gè)日志提供類(注入用,EF Core1.0版本注意注釋),如下:
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());....省略 }
運(yùn)行程序,得到如下調(diào)試信息:
至此,我們就完成了日志的記錄工作.
那么問題來了,在Asp.NET core中,我們可以這樣注入進(jìn)行日志記錄.
如果在別的項(xiàng)目(比如控制臺(tái))中,怎么辦?
下面就來解決這個(gè)問題.
在非Asp.NET core的程序中,我們需要把日志提供器從上下文里注入如下:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){ base.OnConfiguring(optionsBuilder);LoggerFactory loggerFactory = new LoggerFactory();loggerFactory.AddProvider(new MyFilteredLoggerProvider());//注入optionsBuilder.UseLoggerFactory(loggerFactory);}
寫在最后
寫在最后,其實(shí)在EF Core的路線圖中,我們可以看到,在2.0的版本將會(huì)提供一個(gè)更簡(jiǎn)單的日志記錄方式
這段話是在(Features originally considered but for which we have made no progress and are essentially postponed)之后的:
..上面翻譯過來的大概意思就是:我們?cè)瓉砜紤]會(huì)加入的功能,但是現(xiàn)在并沒有進(jìn)展,基本要推遲的特點(diǎn).(..總結(jié)三個(gè)字,然并卵)
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.
嗯..翻譯過來的意思就是..我們想提供一個(gè)更簡(jiǎn)單的日志記錄,比如像EF6.x中的?Database.Log 這樣...()
?
還有一個(gè)比較有趣的東西如下:
在High priority features(高度優(yōu)先的功能)中還有一段話:
Simple command interception?provides an easy way to read/write commands before/after they are sent to the database.
簡(jiǎn)單的命令攔截,將提供在發(fā)送到數(shù)據(jù)庫之前/之后讀取/寫入命令的簡(jiǎn)單方法
我覺得這個(gè)有點(diǎn)類似于EF6.x的IDbCommandInterceptor.
相關(guān)文章:
一步步學(xué)習(xí)EF Core(1.DBFirst)
原文地址:http://www.cnblogs.com/GuZhenYin/p/6862505.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺(tái)或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的一步步学习EF Core(2.事务与日志)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不可思议黑科技,Xamarin移动开发新
- 下一篇: Visual Studio 2017 针