欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
LING to SQL 實(shí)現數據訪(fǎng)問(wèn)通用基類(lèi) - 昆山羽毛球群 50676646 - 博客...

LING to SQL 實(shí)現數據訪(fǎng)問(wèn)通用基類(lèi)

原文地址:http://devermind.com/linq/a-linq-disconnected-mode-abstract-base-class

LINQ to SQL讓人著(zhù)迷,在.Net應用程序當中,.它提供了一種安全,強大和非常靈活的方式執行數據訪(fǎng)問(wèn),在當前微軟傳道者介紹上看,很容易上手。

不幸的是,當你對LINQ進(jìn)行仔細研究后,我發(fā)現在多層架構中使用LINQ的并不是十分容易。

本文介紹用LINQ to SQL實(shí)現數據層的典型的問(wèn)題點(diǎn) ,并提供了一個(gè)簡(jiǎn)單,方便和靈活的方式來(lái)克服它們。

本文附帶的LING to SQL 實(shí)現數據訪(fǎng)問(wèn)通用類(lèi)有以下的特點(diǎn):

  • 實(shí)現了存儲庫模式,你可以用不到10行代碼執行LINQ實(shí)體類(lèi)型的CRUD (Create, Update, Delete)操作。
  • 無(wú)縫協(xié)作,支持LINQ斷開(kāi)模式(Disconnected LINQ Mode)。
  • 在單一數據庫和LINQ實(shí)體間支持透明的數據庫更新和數據加載。
  • 提供為一種方便的功能,在調試你的應用程尋時(shí)候,它把所有執行的SQL語(yǔ)句輸出控制臺。

本文將假定您對LINQ to SQL (也稱(chēng)為DLINQ )有一個(gè)基本的了解并如何使用它。否則,,,回到此網(wǎng)頁(yè),看看本教程入門(mén)系列,如何在多層次應用中使用LINQ to SQL。

存在的問(wèn)題

如果您只是在你的UI層直接用LinqToDataSource對象銜接數據庫,那LINQ to SQL太容易使用了。但是,這種做法不完全面向對象,當然也不是一個(gè)可取的架構,除非你是為了快速編碼和臟亂的應用程序,并且最終沒(méi)有去擴展的它打算。

相反,大多數開(kāi)發(fā)人員把它們的應用程序劃分成若干層,如下:

  • 數據訪(fǎng)問(wèn)層(Data Access Layer)
  • 業(yè)務(wù)層 (Business Layer)
  • 用戶(hù)界面層(UI Layer)

這就是所謂的多層數據庫應用程序設計。LINQ to SQL將用于數據訪(fǎng)問(wèn)層。

LINQto SQL的問(wèn)題是-盡管它的許多優(yōu)點(diǎn)-但是如果要實(shí)現數據層并不是很簡(jiǎn)單。

請看下面的數據庫模式(database schema):

一旦你要加載和保存LINQ實(shí)體到同一個(gè)的數據上下文實(shí)例(data context instance)(這就是所謂“連接模式”),用LINQ實(shí)現數據層非常直接。

例如,讓我們從數據庫中獲取實(shí)體編號為1的客戶(hù),改變屬性first name為“Homer”后在重新儲存到數據庫中。在一個(gè)多層數據庫應用程序中,在UI或業(yè)務(wù)層的某個(gè)地方的代碼可能看起來(lái)就像這樣:

view plaincopy to clipboardprint?

1.         

2.       //create a new repository instance   

3.       CustomersRepository customersRepository = new CustomersRepository();   

4.       //load a customer instance and change it's FirstName;   

5.       Customer customer = customersRepository.Load(2);   

6.       customer.FirstName = "Homer";   

7.       //commmit customer to database   

8.       customersRepository.Save(customer);  

 

最簡(jiǎn)單的方法來(lái)實(shí)現上面使用到的數據層加載和保存功能是:

 

view plaincopy to clipboardprint?

1.         

2.       static DataClassesDataContext context=new DataClassesDataContext();   

3.       public Customer Load(int CustomerID)   

4.       {   

5.       return context.Customers.Single(c => c.ID == CustomerID);   

6.       }   

7.       public void Save(Customer toSave)   

8.       {   

9.       context.SubmitChanges();   

10.   }  

 

種方法是使用連接LINQ模式:數據上下文(data context)在當前作用域一直有效(譯者注:一直保持連接狀態(tài)),所以在把實(shí)體保存到數據庫的時(shí)候,它總是可以重復使用。其中仍然連接到它。

當然,這種做法方便并且在上述的單個(gè)例子中能運行,但它存在嚴重的并發(fā)問(wèn)題,因為一個(gè)數據庫方面是用于所有數據庫操作。

當調用方法Save(),bmitChanges提交的不僅僅是當前Save 方法參數相關(guān)的LINQ實(shí)體,還包括所有改變了的實(shí)體。

但是及時(shí)把這個(gè)缺陷考慮在一邊,使用LINQ在一個(gè)多層ASP.NET應用程序中,您還不能以相同方式實(shí)現數據層。首先,可能要求是這樣,在一個(gè)頁(yè)面請求中,LINQ實(shí)體被加載,然后在下一個(gè)頁(yè)面請求中,它更新并儲存到數據庫中的。.同時(shí),您的原始數據上下文在當前作用域內已經(jīng)無(wú)效的(譯者?。篐TTP協(xié)議是無(wú)狀態(tài)的),造成的您的LINQ實(shí)體游離。

還有許多其他情況下你需要使用斷開(kāi)LINQ模式:例如您實(shí)現的數據庫層可能要作為一個(gè)Web服務(wù),提交(commit)以前序列化LINQ實(shí)體到數據庫等等。

用斷開(kāi)模式的LINQ to SQL實(shí)現數據訪(fǎng)問(wèn)層

所以,在斷開(kāi)的LINQ模式下,我們如何實(shí)現數據層的Save( )方法?

我們必須

  • Detach the entity from the old data context從舊的數據上下文中分離實(shí)體
  • Create a new data context創(chuàng )建一個(gè)新的數據上下文
  • Attach the entity to the new context附加實(shí)體到新的數據上下文
  • Submit changes提交更改

在源代碼,它看起來(lái)像這樣:

 view plaincopy to clipboardprint?

1.         

2.       public Customer Load(int CustomerID)   

3.       {   

4.       DataClassesDataContext context = new DataClassesDataContext();   

5.       return context.Customers.Single(c => c.ID == CustomerID);   

6.       }   

7.         

8.       public void Save(Customer toSave)   

9.       {   

10.   //the old data context is no more, we need to create a new one   

11.   DataClassesDataContext context = new DataClassesDataContext();   

12.   //serialize and deserialize the entity to detach it from the   

13.   //old data context. This is not part of .NET, I am calling   

14.   //my own code here   

15.   toSave = EntityDetacher<Customer>.Detach(toSave);   

16.   //is the entity new or just updated?   

17.   //ID is the customer table's identity column, so new entities should   

18.   //have an ID == 0   

19.   if (toSave.ID == 0)   

20.   {   

21.   //insert entity into Customers table   

22.   context.Customers.InsertOnSubmit(toSave);   

23.   }   

24.   else  

25.   {   

26.   //attach entity to Customers table and mark it as "changed"   

27.   context.Customers.Attach(toSave, true);   

28.   }   

29.   }  

 

現在只要你喜歡,您可以加載修改任意多實(shí)體,并且只提交他們一部分到數據庫。但由于使用斷開(kāi)的LINQ ,這個(gè)程序并不會(huì )感知到LINQ實(shí)體之間的關(guān)系。

例如,假設在業(yè)務(wù)層或用戶(hù)界面層您要做到以下幾點(diǎn):

view plaincopy to clipboardprint?

1.         

2.       //load currently selected customer from database   

3.       Customer customer = new CustomersRepository().Load(1);   

4.       //change the customer's first name   

5.       customer.FirstName = "Homer";   

6.       //add a new bill with two billingitems to the customer   

7.       Bill newbill = new Bill   

8.       {   

9.       Date = DateTime.Now,   

10.   BillingItems =   

11.   {   

12.   new BillingItem(){ItemPrice=10, NumItems=2},   

13.   new BillingItem(){ItemPrice=15, NumItems=1}   

14.   }   

15.   };   

16.   customer.Bills.Add(newbill);   

17.   //create a new provider to simulate new ASP.NET page request   

18.   //save the customer   

19.   new CustomersRepository().Save(customer);  

 

這個(gè)斷開(kāi)模式下,上述Save( )方法將提交變更到FirstName列,但是忽略了new bill和billing items。為了做到這一點(diǎn),我們還需要附加或插入遞歸所有相關(guān)的子實(shí)體(child entities):

view plaincopy to clipboardprint?

1.         

2.       public void Save(Customer toSave)   

3.       {   

4.       //the old data context is no more, we need to create a new one   

5.       DataClassesDataContext context = new DataClassesDataContext();   

6.       //serialize and deserialize the entity to detach it from the   

7.       //old data context. This is not part of .NET, I am calling   

8.       //my own code here   

9.       toSave = EntityDetacher.Detach(toSave);   

10.   //is the entity new or just updated?   

11.   //ID is the customer table's identity column, so new entities should   

12.   //have an ID == 0   

13.   if (toSave.ID == 0)   

14.   {   

15.   //insert entity into Customers table   

16.   context.Customers.InsertOnSubmit(toSave);   

17.   }   

18.   else  

19.   {   

20.   //attach entity to Customers table and mark it as "changed"   

21.   context.Customers.Attach(toSave, true);   

22.   }   

23.   //attach or save all "bill" child entities   

24.   foreach (Bill bill in toSave.Bills)   

25.   {   

26.   if (bill.ID == 0)   

27.   {   

28.   context.Bills.InsertOnSubmit(bill);   

29.   }   

30.   else  

31.     

32.   {   

33.   context.Bills.Attach(bill, true);   

34.   }   

35.   //attach or save all "BillingItem" child entities   

36.   foreach (BillingItem billingitem in bill.BillingItems)   

37.   {   

38.   if (bill.ID == 0)   

39.   {   

40.   context.BillingItems.InsertOnSubmit(billingitem);   

41.   }   

42.   else  

43.   {   

44.   context.BillingItems.Attach(billingitem, true);   

45.   }   

46.   }   

47.   }   

48.   }  

 

不是很復雜,但很多打字(譯者注:翻譯不是很難,但要一句句的理解,還要打很多字)。并且這只是支持一個(gè)微不足道的database scheme和一個(gè)單一的實(shí)體類(lèi)型。.想象一下,如果實(shí)現數據庫層有幾十個(gè)實(shí)體類(lèi)型與幾十個(gè)外鍵關(guān)系,在這個(gè)數據存儲類(lèi)中,你將要為每一個(gè)LINQ實(shí)體寫(xiě)幾十套foreach循環(huán),這不僅是單調乏味,而且還容易出錯。.當你添加新的表,你必須添加幾十foreach循環(huán)。

 

如何避免這些問(wèn)題

在相當多的在線(xiàn)調研后,我實(shí)現了一個(gè)RepositoryBase類(lèi),使用他您可以快速實(shí)現您的數據層,所示為測試通過(guò)的例子。 首先,用對象關(guān)系映射器(譯者注:Visual Studio自帶工具)來(lái)產(chǎn)生序列化的LINQ實(shí)體:在Visual Studio中打開(kāi)dbml文件,在空白區域某處左鍵單擊,彈出屬性窗口,設置“Serialization Mode屬性”為“Unidirectional”。

 

現在您可以繼承RepositoryBase實(shí)現您自己的Repository:

view plaincopy to clipboardprint?

1.       public class CustomersRepository :   

2.       //derive from RepositoryBase with the entity name and   

3.       //data context as generic parameters   

4.       DeverMind.RepositoryBase   

5.       {   

6.       override protected Expression<Func<Customer, bool>> GetIDSelector(int ID)   

7.       {   

8.       //ID needs to be the entity's ID column name   

9.       return (Item) => Item.ID == ID;   

10.   }   

11.   }   

12.   public partial class Customer   

13.   {   

14.   public static RepositoryBase CreateRepository()   

15.   {   

16.   //create and return an instance of this entity type's repository   

17.   return new CustomersRepository();   

18.   }   

19.   }  

您的每一個(gè)實(shí)體的類(lèi)型都照這樣做,你就擁有了一個(gè)工作在斷開(kāi)模式下無(wú)縫數據層。您繼承Repository的類(lèi)自動(dòng)執行下列方法:

 

作為錦上添花的功能,在應用程序調試的過(guò)程中,你還可以通過(guò)輸出控制臺看到執行對數據庫的操作的SQL命令。這多虧了被用于RepositoryBase的SQL調試輸出的Kris Vandermotten 方便的DebuggerWriter組件(譯者注:外國人就是紳士)!

天下有沒(méi)有免費的午餐...

當前的加載(Load)操作中,沒(méi)有任何顯著(zhù)的性能損失,但是當你調用Save or Delete方法時(shí)候,幕后用到一點(diǎn)反射(reflection)操作。

對于絕大多數的數據訪(fǎng)問(wèn)層(DAL)需求,在你的應用程序當中,這可能并沒(méi)有顯著(zhù)的的影響。 但是,如果您正在執行大量的更新/插入/刪除操作,特別是大量的包含嵌套的實(shí)體,那么您可能需要自己寫(xiě)代碼替代Repository的Save / Delete方法。.所有Save / Delete方法都是虛方法(virtual),因此您可以輕易重寫(xiě)(override)他們。

另外請注意, RepositoryBase不支循環(huán)依賴(lài)(circular dependencies)的遞遞歸save 或者 delete操作。

結論

本文將和包括源代碼提供了一個(gè)簡(jiǎn)單,方便和可擴展的方式實(shí)現您的多層LINQ數據層CRUD(譯者注:增,刪,改,查)的方法。.它利用斷開(kāi)模式,并支持保存(saving)和加載(loading)嵌套子實(shí)體(child entities).在Save 和Delete(譯者注:原文為L(cháng)oad,可能原作者筆誤)操作時(shí)候有一個(gè)小小的性能損失,但在性能至關(guān)重要的應用中,您可以重寫(xiě)這些Repositories類(lèi)的Save和Delete。

對于一切,你安心上路,只需幾行代碼。

源代碼

更新的源代碼,本文可以找到這里 。

反饋通緝!

感謝您閱讀這篇文章。如果您有任何提示,問(wèn)題或建議,請讓我知道。我在日常工作中使用這個(gè)類(lèi),因此總是很感興趣就如何進(jìn)一步改進(jìn)。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
VS2008 數據訪(fǎng)問(wèn)層(DAL)的開(kāi)發(fā) (一) (轉)
Entity Framework的原理及使用方式
LINQ 默認欄目 默認欄目 語(yǔ)錄點(diǎn)滴
數據訪(fǎng)問(wèn)層框架設計介紹
ADO.NET入門(mén)教程(一) 初識ADO.NET
EntityFramework優(yōu)缺點(diǎn)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久