Entity Framework 動態構造select表達式

擴展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}

} 改進下:使用參數來賦值

相關文章
相關標籤/搜索