EntityFrameworkCore上下文如何實現繼承?

【導讀】如果我們存在基礎設施服務和其他服務,我們會定義屬于基礎設施服務的上下文以及其他服務的上下文, 而且會獨立部署,此時其他服務需要使用基礎服務,我們都會暴露基礎服務接口給到其他服務調用,這也是常規操作

若在項目較小的情況下且僅內部調用等等,為免去重新定義基礎設施服務上下文以及模型等等,我們大可以將基礎設施服務上下文打成nuget包形式或項目引用方式等等,然后其他服務上下文繼承基礎設施上下文,如此這般,我們就可以操作基礎設施模型,那么我們應該怎么做呢?

實現上下文繼承

我們從頭開講,比如我們定義其他服務上下文以及模型等等

public?class?TestDbContext?:?DbContext
{public?TestDbContext(DbContextOptions<TestDbContext>?options)?:?base(options){}public?DbSet<Test>?Tests?{?get;?set;?}
}[Table("tests")]
public?class?Test
{[Column("id")]public?int?Id?{?get;?set;?}[Column("name")]public?string?Name?{?get;?set;?}
}

接下來我們使用控制臺程序注入上下文并查詢表數據,最基本操作,無需我多言

static?void?Main(string[]?args)
{var?services?=?new?ServiceCollection();services.AddDbContext<TestDbContext>(options?=>{options.UseSqlServer("Data?Source=.;Initial?Catalog=EFCore;User?ID=sa;Password=sa123;");});var?serviceProvider?=?services.BuildServiceProvider();var?context?=?serviceProvider.GetRequiredService<TestDbContext>();var?result?=?JsonConvert.SerializeObject(context.Tests.ToList());
}

c5ddc21cc9da31f695d7453ae44911b7.png

此時上述服務上下文需要調用基礎服務上下文,我們該怎么辦呢?先定義好基礎服務上下文

public?class?BaseDbContext?:?DbContext
{public?BaseDbContext(DbContextOptions<BaseDbContext>?options)?:?base(options){}public?DbSet<User>?Users?{?get;?set;?}
}[Table("users")]
public?class?User
{[Column("id")]public?int?Id?{?get;?set;?}[Column("name")]public?string?Name?{?get;?set;?}[Column("birthdate")]public?DateTime?BirthDate?{?get;?set;?}[Column("address")]public?string?Address?{?get;?set;?}
}

接下來我們將其他服務上下文TestDbContext繼承自上述基礎服務上下文

public?class?TestDbContext?:?BaseDbContext
{public?TestDbContext(DbContextOptions<TestDbContext>?options)?:?base(options){}......??
}

此時編譯會報CS1503錯誤,無法將TestDbContext轉換為BaseContext,因為構造函數參數不匹配,我們知道DbContextOptions是DbContextOptions<T>父類,所以我們只需在BaseDbContext新增一個構造函數即可

public?class?BaseDbContext?:?DbContext
{public?BaseDbContext(DbContextOptions<BaseDbContext>?options)?:?base(options){}public?BaseDbContext(DbContextOptions?options)?:?base(options){}......
}

這樣一來,我們則可以操作基礎服務上下文中的模型,如下

var?context?=?serviceProvider.GetRequiredService<TestDbContext>();var?result?=?JsonConvert.SerializeObject(context.Users.ToList());

03a5587567d429bc71aab53012a870a9.png

我們到這里是不是就大功告成了呢?當然沒有,若此時通過基礎服務上下文直接操作,我們發現會拋出如下異常

c1653ece88a0bff456be6033368d4516.png

啥意思呢?根據大致意思來看,就是說上下文構造函數有問題,所以無法激活創建上下文,那么根本原因在哪里呢?這個問題其實在此前博文有講解 ,甩出源碼如下:

private?static?Func<TContext>?CreateActivator(DbContextOptions?options)
{var?constructors=?typeof(TContext).GetTypeInfo().DeclaredConstructors.Where(c?=>?!c.IsStatic?&&?c.IsPublic).ToArray();if?(constructors.Length?==?1){var?parameters?=?constructors[0].GetParameters();if?(parameters.Length?==?1&&?(parameters[0].ParameterType?==?typeof(DbContextOptions)||?parameters[0].ParameterType?==?typeof(DbContextOptions<TContext>))){returnExpression.Lambda<Func<TContext>>(Expression.New(constructors[0],?Expression.Constant(options))).Compile();}}return?null;
}

首先獲取上下文中聲明的構造函數過濾掉了靜態和公共,且上下文必須有且只能有一個顯式構造函數且參數只能為DbContextOptions<T>,我們恍然大悟,將新增的構造函數訪問修飾符修改為受保護的(protected)即可

public?class?BaseDbContext?:?DbContext
{public?BaseDbContext(DbContextOptions<BaseDbContext>?options)?:?base(options){}protected?BaseDbContext(DbContextOptions?options)?:?base(options){}......
}

10fb6142e0d2780d5bc89a8c3614fb52.png

哦,沒啥可總結的勒,這玩意只能根據經驗猜或者看源碼可得知,再會!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282765.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282765.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282765.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Unity 游戲框架搭建 (九) 減少加班利器-QConsole

為毛要實現這個工具? 在我小時候,每當游戲在真機運行時,我們看到的日志是這樣的。 沒高亮啊,還有亂七八糟的堆棧信息,好干擾日志查看,好影響心情。 還有就是必須始終連著usb線啊&#xff0c;我想要想躺著測試。。。 以上種種原因,QConsole誕生了。 如何使用? 使用方式和QLog…

android藍牙多次后,android – 如何防止BluetoothGattCallback一次多次執行

我的服務有一個BluetoothGattCallback實例public class MyService extends Service {private BluetoothGattCallback callback;Overridepublic void onCreate() {super.onCreate();callback new BluetoothGattCallback() {Overridepublic synchronized void onConnectionState…

美觀又實用,10 款強大的開源 Javascript 圖表庫

2019獨角獸企業重金招聘Python工程師標準>>> 隨著發展&#xff0c;現代 Web 設計在改善體驗和功能的同時&#xff0c;對于美觀的追求也越來越高&#xff0c;可視化、交互式、動態等元素和效果似乎已成為標配。 以下是為開發者推薦的 10 款開源 Javascript 圖表庫&am…

EF CORE 7 RC1 發布

原文鏈接&#xff1a;https://devblogs.microsoft.com/dotnet/announcing-ef7-rc1/[1]原文作者&#xff1a;Jeremy Likness翻譯&#xff1a;沙漠盡頭的狼(谷歌翻譯加持)Entity Framework Core 7 (EF7) Release Candidate 1 已發布&#xff01;該團隊專注于解決缺陷、小幅改進以…

0 重新學習Ubuntu -- 這一段沒怎么學習

在完成了前面的幾個學習后&#xff0c;再沒有進行系統的學習。 雖然在真機上安裝系統&#xff0c;每天都打開&#xff0c;完成以下的工作&#xff1a; 升級軟件用來查看相關的網站在Ubuntu上&#xff0c;現在可以完成辦公、上網、娛樂。 但專業的學習&#xff0c;例如編程方面進…

自定義地圖怎么做成html,自定義html為谷歌地圖制作標記

好吧&#xff0c;似乎Custom Overlays會做我想要的。這是ping層&#xff1a;function PingLayer(bounds, map) {this.bounds bounds;this.setMap(map);}PingLayer.prototype new google.maps.OverlayView();PingLayer.prototype.onAdd function() {var div document.create…

HDU5248:序列變換(二分)

序列變換 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1348 Accepted Submission(s): 593Problem Description給定序列A{A1,A2,...,An}, 要求改變序列A中的某些元素&#xff0c;形成一個嚴格單調的序列B&am…

微服務太分散?使用Fundebug集中式bug監控

摘要&#xff1a; 微服務日志分散&#xff0c;可以使用Fundebug的異常監控將它們集中起來。 當一個項目復雜到一定程度&#xff0c;功能越來越多&#xff0c;隨之對應的模塊也越來越多。 如果都放在一個大的項目下面&#xff0c;共同開發&#xff0c;整合發布&#xff0c;那么會…

html404頁面怎么添加,網站要如何設置自定義404頁面?

之前我們講述過網站設置404頁面對于優化或是用戶體驗的重要意義&#xff0c;大家可移步到《網站為什么要設置404頁面》查看&#xff0c;今天我們講解的是網站要如何設置自己的404頁面。現在大多數空間商都有了404設置的功能&#xff0c;我們可將404頁面上傳至空間里面&#xff…

設計模式之——工廠方法模式

1、工廠方法模式&#xff08;Factory Method&#xff09;工廠方法模式分為三種&#xff1a;11、普通工廠模式&#xff0c;就是建立一個工廠類&#xff0c;對實現了同一接口的一些類進行實例的創建。首先看下關系圖&#xff1a;舉例如下&#xff1a;&#xff08;我們舉一個發送郵…

記一次性能故障排查

最近一次公司服務出了一些性能的問題&#xff0c;主要是內存不釋放。領到任務后就開始展開工作。項目是用.net core 6寫的&#xff0c;在框上應該不會有什么問題&#xff0c;這是大背景。另外服務是部署在k8s上的&#xff0c;于是就和性能測試人員&#xff0c;開發人員搭測試環…

html單選框 點擊取消選中,radio單選框再點擊取消選中

html:html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">單選框選項a選項b選項c選項dcheckradio.js://參數&#xff1a;obj為當前點擊的radio對象function onClickRadioStyle(obj){var…

開啟AngularJS 1.X的學習之路(1)

概念(1) AngularJS 應用 AngularJS 模塊&#xff08;Module&#xff09; 定義了 AngularJS 應用。AngularJS 控制器&#xff08;Controller&#xff09; 用于控制 AngularJS 應用。ng-app指令定義了應用, ng-controller 定義了控制器。eg: <div ng-app"myApp" ng-…

Hello boke!

Hello boke&#xff01;轉載于:https://www.cnblogs.com/yikuan-919/p/9319071.html

ASP.NET Core在.NET 7 RC1中的更新

原文鏈接&#xff1a;https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-7-rc-1/[1]原文作者&#xff1a;Daniel Roth翻譯&#xff1a;沙漠盡頭的狼(谷歌翻譯加持).NET 7 Release Candidate 1 (RC1) 現已推出[2]&#xff0c;其中包括對 ASP.NET Core 的許…

html5 tab菜單切換頁面,11個常用的jQuery TAB切換菜單源碼及制作教程

11個常用的jQuery TAB切換菜單源碼及制作教程SponsorTAB切換式菜單可以方便為我們減少很多網頁布局空間&#xff0c;而且用jQuery的話可以加入一些動畫效果&#xff0c;比如漸變&#xff0c;向左右滑動等&#xff0c;提升一定的用戶體驗&#xff0c;所以TAB菜單目前來說是很流行…

7.16 10.19-10.22

10.19 iptables規則備份和恢復[roothyc-01-01 ~]# service iptables save 保存iptables規則該命令會將規則保存在/etc/sysconfig/iptables將iptables規則備份到一個文件中[roothyc-01-01 ~]# iptables-save>/tmp/ipt.txt將iptables規則備份到ipt.txt文件中從備份規則的文件恢…

走進javascript——不起眼的基礎,值和分號

值 有時我很想知道javascript解析引擎是如何區分一個變量的值&#xff0c;比如下面這段代碼。 var x javascript; //javascript x "hello"; // hello x 555; //555 x null; //null x a; //a is not defined x true; //true 對于數字是直接賦值的&#xff0c;因…

ConcurrentDictionary字典操作竟然不全是線程安全的?

好久不見&#xff0c;馬甲哥封閉居家半個月&#xff0c;記錄之前遇到的一件小事。ConcurrentDictionary<TKey,TValue>絕大部分api都是線程安全的[1]&#xff0c;唯二的例外是接收工廠函數的api&#xff1a;AddOrUpdate、GetOrAdd&#xff0c;這兩個api不是線程安全的&…

碼農小汪-Hibernate學習8-hibernate關聯關系注解表示@OneToMany mappedBy @ManyToMany @JoinTable...

近期我也是有點郁悶&#xff0c;究竟是程序中處理關聯關系。還是直接使用外鍵處理關聯關系呢&#xff1f;這個的說法不一致&#xff01;程序中處理這樣的關聯關系的話。自己去維護這樣的約束。這樣的非常樂觀的一種做法&#xff01;或者是直接在數據庫中處理這樣的直接的外鍵關…