EntityFramework Core查询数据基本本质
【導讀】在EntityFramework Core中、當查詢出數據后,是如何將數據映射給實體的呢?本節我們預先做個基本探討,后續給出其底層原理本質
前不久,我們在探索性能時,給出利用反射達到性能瓶頸時的方案即使用委托,如下:
var?setId?=?(Action<Test,?int>)Delegate.CreateDelegate(typeof(Action<Test,?int>),?null,?typeof(Test).GetProperty("Id").GetSetMethod());上述我們通過委托方式來代替反射,可能我們也想到了另外一種方案,通過lambda構建表達式的方式
查詢數據基本本質
首先我們來看看如何手動構建lambda表達式來獲取或設置數據,廢話不多講,直接見代碼
public?static?Action<T,?object>?Set<T>(PropertyInfo?propertyInfo) {var?targetType?=?propertyInfo.DeclaringType;var?setMethod?=?propertyInfo.GetSetMethod();var?type?=?propertyInfo.PropertyType;var?target?=?Expression.Parameter(targetType,?"t");var?value?=?Expression.Parameter(typeof(object),?"d");var?condition?=?Expression.Condition(Expression.Equal(value,?Expression.Constant(DBNull.Value)),Expression.Default(type),Expression.Convert(value,?type));var?body?=?Expression.Call(Expression.Convert(target,?setMethod.DeclaringType),setMethod,condition);return?Expression.Lambda<Action<T,?object>>(body,?target,?value).Compile(); }當我們獲取到數據庫數據時,緊接著需要將其對應列數據賦值給對應屬性,此時根據列類型需構建表達式判斷條件(Condition),繼而調用其設置方法,最后構建整體lambda進行編譯執行,對于獲取基本同理,不再解釋
public?static?Func<T,?object>?Get<T>(PropertyInfo?propertyInfo) {var?targetType?=?propertyInfo.DeclaringType;var?getMethod?=?propertyInfo.GetGetMethod();var?target?=?Expression.Parameter(targetType,?"t");var?body?=?Expression.Convert(Expression.Call(target,?getMethod),?typeof(object));return?Expression.Lambda<Func<T,?object>>(body,?target).Compile(); }那么問題來了,手動構建lambda表達式和上述直接通過創建委托方式,哪種方式更佳呢?
單從代碼量上和所給例子來看,理論上是利用創建委托方式更佳,但是其潛在的問題是,通過創建委托,我們必須遍歷實體所有屬性,那么像上述利用lambda表達式難道就不用了?
事實上,完全不用,手動構建lambda的好處在于,我們可手動構建實體所有屬性,然后一次性賦值從而改善性能
至于如何一次性獲取對應實體所有屬性,然后手動構建lambda并賦值,這才是EntityFramework Core的妙處設計所在,后續文章我會詳細給出
手動構建lambda的場景很多,再比如構建自動化腳本,對lambda使用到爐火純青地步,那么自身整體核心競爭力將更上一臺階
?????是的,我的文章都是建立在基礎上的一點額外探索,比如微服務、k8s等等流行的玩意當前還完全沒有涉及,一來實際項目中,還未應用,二是,不愿淺嘗輒止,意義不大。萬變不離其宗,所有我們看過的代碼難道不都是語法組合嗎?
總結
以上是生活随笔為你收集整理的EntityFramework Core查询数据基本本质的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 93.7%的程序员!竟然都不知道Redi
- 下一篇: 万级 K8S 集群背后,etcd 如何保