擴展ef自動映射須要查詢的字段 好比咱們須要返回某些字段會採用以下的寫法html
可是發現每次都去寫select若是字段不少不想去一個一個查詢出來,就想指定一個dto的類型sql
他就能查詢dto裏邊的字段,而後自動映射到dto裏邊去就能夠減小不少工做量了數據庫
咱們把lambda表達式提到外面去express
這種能夠,可是下面這種構建一個dto_user怎麼都不行要報錯學習
找了好久把表達式變成func就能夠了測試
或者調用表達式樹的Compile方法生成func固然也是同樣的.net
有了這個就能夠經過類型+反射動態構建查詢的字段了code
測試的原型htm
測試成功!很高興因而去封裝了一個通用的擴展方法!對象
用法:
這樣就會自動映射DTO_User了,寫出來了仍是很激動
可是很快就發現問題了,他竟然是查詢的所有!,而後那個查詢須要字段的他竟然是在內存中操做了,
每次都會查詢所有字段出來
其實這個擴展方法實現了動態拷貝,能夠做爲解決這個問題的第二個步驟,把須要的字段查詢出來後
在進行動態拷貝,平時進行對象轉化的時候也能夠直接用
而後測試發現select若是傳表達式樹他會去解析成sql,他會轉換成須要查詢的字段sql
從返回的IQueryable接口就知道,他是會生成的sql的,可是若是咱們傳遞的是Func呢
返回的倒是IEnumerable,固然是在內存中操做的了,
數據庫查詢只有IEnumerable纔回執行到數據庫 IQueryable只拼接sql
由於func只能在裏邊看成方法去執行 而表達式數確能夠獲得不少東西好比參數返回值什麼的 這也是他們的區別
想要真正實現自動映射到DTO,並且只查詢的仍是那幾個字段,那麼這裏要想辦法動態建立表達式樹,
不能直接傳func
這就須要瞭解ef內部是怎麼解析的這個表達式樹,還有表達式樹是怎麼動態生成的了
表達式樹的學習:http://www.cnblogs.com/li-peng/p/3154381.html
這篇文章很好的解決了動態構建表達式樹:http://www.cnblogs.com/JimmyZheng/archive/2012/02/23/2364154.html
http://blog.csdn.net/cauchy8389/article/details/23529857
http://bbs.csdn.net/topics/390790484
http://bbs.csdn.net/topics/390813750
查了2天資料終於找到解決方案了使用MemberInitExpression就能夠動態構建
https://msdn.microsoft.com/zh-cn/library/system.linq.expressions.memberinitexpression.aspx
msdn上面的資料
class Animal { public string Species {get; set;} public int Age {get; set;} }
public static void CreateMemberInitExpression() { System.Linq.Expressions.NewExpression newAnimal = System.Linq.Expressions.Expression.New(typeof(Animal));
System.Reflection.MemberInfo speciesMember = typeof(Animal).GetMember("Species")[0]; System.Reflection.MemberInfo ageMember = typeof(Animal).GetMember("Age")[0]; // Create a MemberBinding object for each member // that you want to initialize. System.Linq.Expressions.MemberBinding speciesMemberBinding = System.Linq.Expressions.Expression.Bind( speciesMember, System.Linq.Expressions.Expression.Constant("horse")); System.Linq.Expressions.MemberBinding ageMemberBinding = System.Linq.Expressions.Expression.Bind( ageMember, System.Linq.Expressions.Expression.Constant(12)); // Create a MemberInitExpression that represents initializing // two members of the 'Animal' class. System.Linq.Expressions.MemberInitExpression memberInitExpression = System.Linq.Expressions.Expression.MemberInit( newAnimal, speciesMemberBinding, ageMemberBinding); Console.WriteLine(memberInitExpression.ToString()); // This code produces the following output: // // new Animal() {Species = "horse", Age = 12}
} 改進下:使用參數來賦值