要專業系統地學習EF推薦《你必須掌握的Entity Framework 6.x與Core 2.0》。這本書作者(汪鵬,Jeffcky)的博客:https://www.cnblogs.com/CreateMyself/
現在來到分布式事務。在弄這個之前我對分布式一點經驗也沒有。簡單來說一下分布式,就是你有多個數據庫。
不過我碰到的“MSDTC不可用”的問題實在是無法解決。所以只能是記錄一下我遇到的問題,和一些過程。
上次我們知道平時一般的操作,都是會默認被事務包裹,當我們調用一次SaveChanges方法就會開啟一個事務。
然后了解到EF中提供的BeginTransaction()和UseTransaction()兩個方法。
BeginTransaction()能夠讓我們像ADO中使用事務的那種方式使用。而且調用多個savechanges方式只會開啟一個事務,但是必須要調用一次SaveChanges才能成功操作數據。
UseTransaction方法允許上下文加入已經運行的事務中,它可以接受一個事務對象。
那么如果我們的數據存在多個數據庫中呢?就有了分布式的考慮。怎么做呢?
你可能想到可以通過嵌套上下文,使用UseTransaction來接受另一個上下文的事務。但是不可以。因為UseTransaction接受的事務對象不是EF中定義的事務,而是System.Data.Common.DbTransaction類型的,也就是ADO中的事務類型
那么我們ado和EF混着用?這個應該是可以的,但是我沒有去試。
那么現在就直接來說一個很重要的類:TransactionScop
可以看到這種方式正是我們想要的,DB1_Context 和 DB4_Context 分別對應兩個數據庫,一個本地,還有一個是我遠程服務器上的數據庫。 通過TransactionScop就可以實現分布式事務。

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew)) { var db1_ctx = new DB1_Context(); var db4_ctx = new DB4_Context(); try { db1_ctx.Students.Add(new Student { Name = "小懵", Score = 11 }); db1_ctx.SaveChanges(); db4_ctx.Books.Add(new Book { Name="西游記",PageSize=670}); db4_ctx.SaveChanges(); scope.Complete(); } catch (Exception e) { throw e; } finally { db1_ctx.Dispose(); db4_ctx.Dispose(); } }
看一下我項目的文件結構
這里我要記錄一下使用程序包管理控制台做數據遷移,將不同的上下文分別創建不同的文件夾
比如我為DB1_Context上下文開啟遷移
enable-migrations -ContextTypeName:_20190131.DbContexts.DB1_Context -MigrationsDirectory:Migrations\DB1
ContextTypeName就是上下文的類型名稱,MigrationsDirectory就是你將要創建的文件夾
如果說你記不住命令,可以寫了“-”后按Tab鍵就會出現提示。如果說沒有提示,那么就是你前面的語句寫錯了。命令不同區分大小寫,但是你自己提供的值還是要區分的,畢竟DBContext和dbcontext在VS中還是兩個不同的兩個類
命令后面的冒號可寫可不寫,比如:ContextTypeName:DBcontext 或者 ContextTypeName DBcontext 我還是覺得寫上問號好一點,可讀性高。
那么添加遷移文件
add-migration -ConfigurationTypeName:_20190131.Migrations.DB1.Configuration -Name:db1001
更新到數據庫
update-database -ConfigurationTypeName:_20190131.Migrations.DB1.Configuration -verbose
現在來記錄一下我碰到的問題,我也不知道會這么麻煩,對我來說不過是多了一個數據庫而已。
首先我通過EF在MSSQL上的一個實例創建了兩個數據庫DB1和DB2,於是我執行上面的代碼,發現報錯了,他說MSDTC不可用。
那么MSDTC是什么?協調跨多個數據庫、消息隊列、文件系統等資源管理器的事務。如果停止此服務,這些事務將會失敗。如果禁用此服務,顯式依賴此服務的其他服務將無法啟動。
反正涉及到分布式就需要配置MSDC,網上有很多圖文並茂的配置,但都是一樣的。難道都不一樣么?難道怎么配置都行么?呵呵
最終我沒有解決這個問題。
然后我想到是不是因為兩個數據庫都是在本地,都是在同一個實例中造成的。於是我今天又在我的服務器上安裝了一個MSSQL2017,費了
老半天勁終於我本地數據庫能夠連接遠程服務器的數據庫實例了。
但是還是出席那MSDTC不可用的問題。行吧,就到這里。