西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁(yè)業(yè)內(nèi)動(dòng)態(tài) 業(yè)內(nèi)資訊 → Linq 的一些數(shù)據(jù)庫(kù)處理小技巧

Linq 的一些數(shù)據(jù)庫(kù)處理小技巧

相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來(lái)源:百度搜索時(shí)間:2010/7/26 14:36:17字體大。A-A+

作者:Linq點(diǎn)擊:850次評(píng)論:0次標(biāo)簽: Linq 數(shù)據(jù)庫(kù)

  • 類型:遠(yuǎn)程監(jiān)控大小:4.6M語(yǔ)言:中文 評(píng)分:5.5
  • 標(biāo)簽:
立即下載

使用linq的ToArray() ToList() ToDictionary()

當(dāng)我們對(duì)某個(gè)Ienumerable<T>對(duì)象下達(dá)where等條件式時(shí),所取得的結(jié)果會(huì)是一個(gè)實(shí)現(xiàn)了Ienumerable<T>接口的對(duì)象,此時(shí)所有指定的條件式都尚未執(zhí)行比對(duì)的操作,而只是的到了一個(gè)WhereIterator對(duì)象,拿到了由編譯器對(duì)linq expression 進(jìn)行分析之后所建立的delegate 和string。當(dāng)通過(guò)此Ienumerable<T>對(duì)象獲得Enumerator對(duì)象,并調(diào)用MoveNext函數(shù)時(shí)(foreach會(huì)觸發(fā)該函數(shù)),where Iterator開始起作用,該對(duì)象才會(huì)一筆一筆地對(duì)元素進(jìn)行條件比對(duì)。這一模式不僅用于LINQ TO Objects, 同時(shí)也用于LINQ To XML, LINQ ToDataSet 乃至LINQ To SQL, LINQ TO Entities。

但ToArray()等函數(shù)會(huì)以foreach一一巡覽Ieunmerable<T>對(duì)象中的所有元素并進(jìn)行比較,然后將符合條件的元素方放在Array中返回。

那么,操作這樣一個(gè)比較過(guò)的Array 或者 List 對(duì)象,顯然比直接操作必須在取得元素前進(jìn)行比對(duì)條件的對(duì)象集來(lái)的有效率

LINQ Expression無(wú)法完全取代函數(shù)調(diào)用。以Where為例。當(dāng)使用函數(shù)時(shí),我們可以寫下很復(fù)雜的Lambda Exression

Var pq = new[]{"ybwang", "dingmeng", "yhzhou"}
Var p5 = p1.Where(
x=>{
Bool result = false;
sqlConnection conn = new SqlConnection("…...");
Conn.Open();
Return result;
}
)
這是無(wú)法以單純的LINQ Expression 辦到的,如果硬要以LINQ Expression 來(lái)完成,就必須使用靜態(tài)函數(shù)或者是Extension Method 才行。所以學(xué)會(huì)如何調(diào)用Extension Method 以及運(yùn)用 Lambda Expression, 是活用Linq to Object 的不二法門。

c#3.0只是單純地把LINQ Expression 轉(zhuǎn)成object.Select(),

如果你自己打造了一個(gè)類Persons<T>,

Public class Persons<T>{
Private List<T> _list = new List<t>();
Public T this[int index]
{
Get{
Return _list[index];
}
}

Public void add[T item]{
_list.Add(item);
}
}
你用from o in Persons1 select o 的時(shí)候,由于這個(gè)類沒(méi)有實(shí)現(xiàn)Ienumerable<T>接口,則它將該Lambda表達(dá)式轉(zhuǎn)換為Select()方法之后,會(huì)因?yàn)檎也坏竭@個(gè)方法而報(bào)錯(cuò)。于是你得自己寫個(gè)Extension方法,示例如下

public static class PersonsExtension{
public static Persons<TResult> Select<TSource, TResult>(this Persons<TSource>, Func<TSource, TResult> selector){
//select elements using the Fucn
//return result;
}
}
可見(jiàn),選擇過(guò)程的控制權(quán)在我們手上


Linq to sql 查詢返回的那個(gè)東西,代表這一組sql語(yǔ)句,也就是說(shuō)你寫下var result = from …..的時(shí)候并沒(méi)有去數(shù)據(jù)庫(kù)進(jìn)行查詢,當(dāng)你真正用到數(shù)據(jù)時(shí),比如對(duì)result進(jìn)行foreach時(shí),才會(huì)用result里頭的sql語(yǔ)句去數(shù)據(jù)庫(kù)進(jìn)行查詢,查詢過(guò)程 默認(rèn)使用的是連接模式,即用sqlDataReader來(lái)讀數(shù)據(jù)。

示例一

aDataContext c = new aDataContext();

var result1 = from c1 in c.Customers select c1;
var result2 = from c2 in c.Customers select c2;

foreach(var item in result1){
foreach(var item2 in result2){
//do something
}
}
這是可以的,由于result1和result2屬于同一個(gè)context,當(dāng)result2開始去嘗試連接數(shù)據(jù)庫(kù)時(shí),result1會(huì)把它要的數(shù)據(jù)全部提取出來(lái),緩存到一個(gè)DataTable中,然后綁定到該DataTable,好讓result2綁定到數(shù)據(jù)庫(kù)

實(shí)例二

aDataContext c1 = new aDataContext();
aDataContext c2 = new aDataContext();

var result1 = from c1 in c1.Customers select c1;
var result2 = from c2 in c2.Customers select c2;

foreach(var item in result1){
foreach(var item2 in result2){
//do something
}
}
就不行了,因?yàn)檫@種緩存機(jī)制之適應(yīng)于同一個(gè)dataContext的不同result



有些適用于Linq to Object 的語(yǔ)法,并不適用于Linq to SQL

示例

static void main(string [] args){
var list = new [] {"A", "B", "C"};
var result = from s1 in list where CheckMe(s1) select s1;

foreach(var item in result){}
}

static bool CheckMe(string item){
return true;
}

這是可以的,但在Linq to SQL中

static void main(string [] args){
aDataContext context = new aDataContext();
var result = from s1 in context.Customers where CheckMe(s1) select s1;

foreach(var item in result){}
}

static bool CheckMe(string item){
return true;
}
這是不行的,因?yàn)閘inq不知道該如何將CheckMe函數(shù)轉(zhuǎn)化成sql語(yǔ)句。

這種情況,你可已先調(diào)用ToArray或者ToList函數(shù),使得取回的對(duì)象變?yōu)橐话愕腃ollection,于是就進(jìn)入了Linq to Object 的范圍,可以用Linq to Object 來(lái)操作它了。

在LINQ TO SQL 默認(rèn)模式中,調(diào)用submitChanges函數(shù)更新數(shù)據(jù)之前會(huì)激活一個(gè)Transaction,若期間發(fā)生任何錯(cuò)誤時(shí)會(huì)拋出一個(gè)異常,終止更新操作并調(diào)用Transcation的RollBack函數(shù)來(lái)恢復(fù)事務(wù)前的狀態(tài)。

Linq to sql 為Entity Class的每個(gè)屬性提供了Delay Load 屬性,當(dāng)該屬性的Delay Load被設(shè)置為True時(shí),Linq to SQL于擷取時(shí)便不會(huì)擷取該字段,而是等到該屬性第一次被訪問(wèn)時(shí)才下達(dá)一個(gè)SQL指令由數(shù)據(jù)庫(kù)擷取該字段數(shù)據(jù)。往往將一些二進(jìn)制data的 Delay Load設(shè)置成true

在lts(Linq To SQL)中使用select new 時(shí),所select 出來(lái)的對(duì)象是只讀的。這些對(duì)象和數(shù)據(jù)庫(kù)里邊的行并沒(méi)有什么聯(lián)系,不像是直接選出來(lái)的那些Entity Object, 你修改他們?cè)僬{(diào)用context.Submit(),就會(huì)將修改提交到數(shù)據(jù)庫(kù)



class Program{
static void Main(string[] args){
test();
}

static test(){
aDataContext context = new aDataConetxt();
var result = context.ExecuteQuery<OrdersWithTotal>("select orderId, sum(UnitPrice * Quantity) as Totla from [Order Details] group by orderId");

foreach(var item in result){
Console.WriteLine("Order Id: {0} Total : {1}", item.OrderId, item.Total);
}
}
}

public class OrdersWithTotal{
public int OrderId{get; set}
public Decimal Total{get; set}
}
當(dāng) Linq to Sql 無(wú)法滿足要求時(shí),可以用ExecuteQuery函數(shù)來(lái)直接執(zhí)行SQL指令。它需要一個(gè)類型參數(shù),該函數(shù)為每一行創(chuàng)建指定類型的對(duì)象,此處就是OrderWithTotal.然后將相同名字的字段值填入同名的屬性。這也是為何查詢語(yǔ)句里會(huì)出現(xiàn)as Total 的緣故。as Total ,則生成的OrdersWithTotal對(duì)象的Total屬性會(huì)是空的。

DataContext有一個(gè)Translate<T>(IDataReader)函數(shù),用于從實(shí)現(xiàn)了IDataReader的對(duì)象中獲取實(shí)體對(duì)象

相比于ExecuteQuery(), Translate()是架構(gòu)與IDataReader之上,所以我們可以通過(guò)ODBC、OLEDB、Oracle等ADO.Net Provider將取得的IDataReader對(duì)象轉(zhuǎn)成Entity Objects,對(duì)于轉(zhuǎn)文件、匯入等功能來(lái)說(shuō),Translate函數(shù)相當(dāng)好用。

但它有個(gè)限制,就是只能對(duì)返回對(duì)象做一次foreach,不過(guò)我們?nèi)匀豢梢酝ㄟ^(guò)ToList來(lái)跨越此限制

另外,該函數(shù)執(zhí)行之后,所取得的Entity Object 會(huì)被加入到DataContext中,受dataContext所管轄,因此你可以對(duì)這些對(duì)象做修改,然后調(diào)用dataContext.Submit將改后的數(shù)據(jù)寫回?cái)?shù)據(jù)庫(kù)

    相關(guān)評(píng)論

    閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過(guò)難過(guò)
    • 5 囧
    • 3 圍觀圍觀
    • 2 無(wú)聊無(wú)聊

    熱門評(píng)論

    最新評(píng)論

    第 9 樓 四川成都鐵通ADSL 網(wǎng)友 客人 發(fā)表于: 2010/10/9 21:00:58
    騰訊是害蟲,騰訊是變態(tài)。騰訊出過(guò)的游戲,沒(méi)有一個(gè)是正版.

    支持( 0 ) 蓋樓(回復(fù))

    第 8 樓 廣東深圳電信 網(wǎng)友 客人 發(fā)表于: 2010/9/26 23:03:21

    支持( 0 ) 蓋樓(回復(fù))

    第 7 樓 河南焦作焦作師范高等專科學(xué)校 網(wǎng)友 客人 發(fā)表于: 2010/9/16 18:24:18

    支持( 0 ) 蓋樓(回復(fù))

    第 6 樓 上海楊浦有線通 網(wǎng)友 客人 發(fā)表于: 2010/9/1 18:46:47

    支持( 0 ) 蓋樓(回復(fù))

    第 5 樓 山西太原金玉網(wǎng)吧(山西大學(xué)商務(wù)學(xué)院) 網(wǎng)友 客人 發(fā)表于: 2010/9/1 13:32:41

    支持( 0 ) 蓋樓(回復(fù))

    第 4 樓 廣東清遠(yuǎn)聯(lián)通 網(wǎng)友 客人 發(fā)表于: 2010/8/20 9:21:34

    支持( 0 ) 蓋樓(回復(fù))

    第 3 樓 湖北宜昌聯(lián)通 網(wǎng)友 客人 發(fā)表于: 2010/8/14 22:42:22

    支持( 0 ) 蓋樓(回復(fù))

    第 2 樓 甘肅平?jīng)雎?lián)通 網(wǎng)友 客人 發(fā)表于: 2010/8/5 13:53:09

    支持( 0 ) 蓋樓(回復(fù))

    第 1 樓 江蘇徐州九州職業(yè)技術(shù)學(xué)院 網(wǎng)友 客人 發(fā)表于: 2010/7/30 18:44:18

    支持( 0 ) 蓋樓(回復(fù))

    發(fā)表評(píng)論 查看所有評(píng)論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過(guò)審核才能顯示)