码迷,mamicode.com
首页 > 其他好文 > 详细

Entity Framework-LINQ

时间:2014-12-08 19:13:22      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   使用   sp   

Linq是.Net的一個重要的突破,Linq的主要目的是用來作為.Net中的一種通用查詢語言.

Linq設計的目的是針對查詢,不包含新增 修改 刪除等資料異動的功能,因此在EF中Linq當然也只能用於作為查詢,其他部分都與Linq沒有任何關係.

使用Linq的的最大好處是Linq是一種基於物件的強型別的查詢語法,因此可以很容易在編譯時期就能確認語法是否有問題.

 

對於Linq必須要有個概念,Linq本身設計上是可以跨不同資料來源,譬如XML,DataSet…等等.

所以不同的資料來源會有對應的Linq Library,目前內建於.Net中的Linq Libray.

1.Linq to Object

2.Linq to XML

3.Linq to ADO.Net

而且他的資料來源,Linq提供了擴展方式.譬如網路上可以找到WMI to Linq等相關Library,如果有能力也可以自行設計擴展.

因此相同的對於EF而言,因此EF也擴展了Linq來支持.

 

bubuko.com,布布扣

 

Linq在撰寫時有兩種方式

1.Linq語法

List<Customer> customers = ...;
var q = from c in customers
        where c.Id == 1;

2.Lambda表示式

List<Customer> customers = ...;
var q = customers.Where(c => c.Id == 1);

這兩種寫法上最後的結果都相同,效能也相同,不過建議使用第2種,對於操作Linq會更有彈性.

 

EF中對於Linq的擴展比其他資料來源比較複雜些.

底下為EF中的架構圖

bubuko.com,布布扣

由於EF在架構上是沒有綁定資料庫,EF提供了EntityClient Data Provider概念,而Data Provider最終是透過ADO.Net去存取資料庫.

因此當一個非.Net原生支援(目前只有MSSQL)的資料庫要能支援EF必須提供ADO.Net provider外還必須提供EntityClient Data Provider.

EntityClient Data Provider的主要目的是用來轉譯Linq與Entity SQL Query成ADO.Net的Command(SQL).

因此在Linq在EF中並不是所有功能都支持.必須看EntityClient Data Provider有沒有(能不能)將Linq語法轉譯成ADO.Net的Command(SQL).

而對於Linq,EF已經定義了一些標準ANSI通用的查詢對應函數.譬如Contains函數對應LIKE語法.

var q = dbContext.Customers.Where(c => c.Name.Contains("XXX"));

但由於EF設計上並沒有綁定資料庫,因此對於一些特定資料庫的特定功能,EF提供了另外的擴展機制來處理.

譬如在MS-SQL可以透過SqlFunctions這種類別來使用對應到MS-SQL中的特定方法,譬如

var q = dbContext.Customer.Where(c => SqlFunctions.DateDiff("ss", c.CreatedDate, DateTime.Today) > 0);

上面例子透過SqlFunctions中的DateDiff方法去對應SQL語法中的DATEDIFF函數,當然這樣做也代表這個語法綁訂了MS-SQL.

此外對於User Define Function(使用者自訂函數)部分EF也有方式提供擴展,後續章節再針對此部分做說明.

 

在EF中使用Linq常常會問的問題或是錯誤.

譬如底下的Code

var q = dbContext.Customers.Where(c => c.Name.Contants("XX") && Check(c));

Check函數是另外撰寫用來檢查是否符合的一段C#程式,中間包含了很多複雜邏輯.

由上面的觀念可以知道這個語法執行時一定會出錯,因為EntityClient Data Provider並沒有(也不知道),Check函數應該要怎麼翻譯成ADO.Net的Command(SQL).

所以我們些調整

var q = dbContext.Customers.Where(c => c.Name.Contants("XX")).ToList().Where(c => Check(c));

將語法分為兩段先透過.ToList()方法將資料從資料庫中取回到記憶體中,因為這時候資料已經在記憶體了,因此第二段的Where實際上是透過Linq to Object去操作而非EF.

而要注意一點,在操作EF時必須要了解甚麼時候會把資料從資料庫取回.

否則如果上面的例子寫成如下語法

var q = dbContext.Customers.ToList().Where( c.Name.Contants("XX") && c => Check(c));

雖然結果是相同的,但效能差異相當大

因為.ToList()方法執行時會把所有資料庫中的Customers資料拉回到記憶體中,然後在程式中去執行Where去做塞選.

而前述的方法透過Where(c => c.Name.Contants(“xx”))在查詢時先用SQL語法去塞選結果到記憶體中再做後續檢查.

Entity Framework-LINQ

标签:style   blog   http   io   ar   color   os   使用   sp   

原文地址:http://www.cnblogs.com/programlin/p/EF_LINQ.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!