課程代碼課件09-linq表達(dá)式詳細(xì)案例_第1頁
課程代碼課件09-linq表達(dá)式詳細(xì)案例_第2頁
課程代碼課件09-linq表達(dá)式詳細(xì)案例_第3頁
課程代碼課件09-linq表達(dá)式詳細(xì)案例_第4頁
課程代碼課件09-linq表達(dá)式詳細(xì)案例_第5頁
已閱讀5頁,還剩59頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

說明:與SQL命令中的Where操作包括varqfromcinwherec.City==select1994varqfromeinwheree.HireDate>=newDateTime(1994,1,selectvarqfrompinwherep.UnitsInStock<=p.ReorderLevel&&!p.Dis select篩選出篩選出UnitPrice10varqfrompinwherep.UnitPrice>10m||selectwhere以篩選出UnitPrice10varqdb.Products.Where(p=>p.UnitPrice> 返回集合中的一個元素,其實(shí)質(zhì)就是在SQLTOP1)Shippershipper=元素:選擇元素:選擇CustomerID為“BONAP”Customercust=db.Customers.First(c=>c.CustomerID==條件:選擇運(yùn)費(fèi)大于條件:選擇運(yùn)費(fèi)大于10.00Orderord=db.Orders.First(o=>o.Freight>LINQLINQtoSQL(2適用場景:o(∩_∩)o…說明:和SQLselectselect及所接子句是放在表達(dá)式最后并把子句中的變量也就是結(jié)果返回回來;延遲。Select/Distinct9種形式,分別為簡單用法、類型形式、條件形式、指定類型形式、篩選形式、整形類型形式、嵌套類型形式、本地方法調(diào)用形式、Distinct形式。這個示例返回僅含客戶聯(lián)系人的序列。varqfromcinselect 這就是延遲加載(deferredloading)。如果,在 的時候就返回的結(jié)果集是對象的集合。你可以使用ToList()或ToArray()方法把查詢結(jié)果先進(jìn)行保存,然后再對這個集合進(jìn)行查詢。當(dāng)然延遲加載(deferredloading)SQL 類型是C#30中新特性。其實(shí)質(zhì)是編譯器根據(jù)我們自定義自動產(chǎn)生一個 類型還依賴于另外一個特性:支持根據(jù)property來創(chuàng)建對象。比如,vard=new{Name="s"};編譯器自動產(chǎn)生一個有property叫做Name的 類,然后按這個類型分配內(nèi)存,并初始化對象。但是vard=new{"s"};是編譯不通 類中的property的名字。例如stringc="d";vard=new{c};則是可以通過編譯的。 類帶有叫c的property。例如下例:new{c,ContactName,c.Phone};ContactName和Phone都是在映射文件中定義與表中字段相對應(yīng)的property。編譯器 兩個屬性,為ContactName和Phone,然后根據(jù)數(shù)據(jù)初始化對象。另外編譯器還可以重命名property的名字。varqfromcinselectnew{c.ContactName,上面語句描述:使用SELECT和的序varqfromeinselect Name=e.FirstName+""+ Phone=上面語句描述:使用SELECT上面語句描述:使用SELECT 類型返回僅含雇 一個字段“Name”HomePhone字段重命名為Phonevarqfrompinselect HalfPrice=p.UnitPrice/varqvarqfrompinselect Availability p.UnitsInStock-p.UnitsOnOrder<0 "OutOfStock":"In上面語句描述:使用SELECT 類型返回所有產(chǎn)品的ID以及HalfPrice(設(shè)置為產(chǎn)品單價除以2所得的值)的序列說明:生成SQL語句為:casewhenconditionthenelse上面語句描述:使用SELECTvarqfromeinselectnew FirstName= LastName=上面語句描述:使用上面語句描述:使用SELECT和已知類型返回雇 的序列wherevarqfromcinwherec.City==selectvarvarqfromcinselectnew Info=new panyName, ContactInfo=new{c.ContactName,語句描述:使用SELECT和 上面語句描述:使用SELECT和WHERE返回僅含倫敦客戶聯(lián)系 的序列 對象,而這 對象中,其屬性也是 對象說明:返回的對象集中的每個對象說明:返回的對象集中的每個對象DiscountedProductsvarqfromoinselectnew DiscountedProducts fromodin whereod.Discount> selectDiscount=語句描述:使用嵌套查詢返回所有訂單及其OrderID語句描述:使用嵌套查詢返回所有訂單及其OrderID這個例子在查詢中調(diào)用本地方法PhoneNumberConvertervarq=fromcin wherec.Country=="UK"||c.Country== select Phone= InternationalPhone PhoneNumberConverter(c.Country, publicstringPhoneNumberConverter(stringCountry,string{Phone=ce("",ce(")",")-switch case return"1-"+ case return"44-"+ return}下面也是使用了這個方法 轉(zhuǎn)換為國際格式并創(chuàng)建下面也是使用了這個方法 轉(zhuǎn)換為國際格式并創(chuàng)建 doc=newX newXElement("Customers",fromcin wherec.Country=="UK"||c.Country== select(new newXAttribute("CustomerID", new new SQL語句為:SELECTDISTINCT[CityFROMvarq=fromcinselectc.City說明:返回集合中的元素個數(shù),返回INTSQL語句為:SELECTCOUNT(*)varq=2.2.varq=db.Products.Count(p=>LONGLongCount來統(tǒng)計(jì)元素個數(shù),它返回longSQL語句為:SELECTCOUNT_BIG(*)FROMvarq=說明:返回集合中數(shù)值類型 和,集合應(yīng)為INT類型集合;不延遲。生成SQL語句為:SELECTSUM(…)varq=db.Orders.Select(o=>varq=db.Products.Sum(p=>SQL語句為:SELECTMIN(1.varq=db.Products.Select(p=>2.2.varq=db.Orders.Min(o=>varcategoriesfrompingrouppbyp.CategoryIDintoselectnew CategoryID= CheapestProducts fromp2in wherep2.UnitPrice==g.Min(p3=> selectSQL語句為:SELECTMAX(…)1.varq=db.Employees.Select(e=>varq=db.Products.Max(p=>varcategoriesfrompingrouppbyp.CategoryIDintoselectnew MostExpensiveProducts fromp2in wherep2.UnitPrice==g.Max(p3=> selectSELECTAVG(…)varq=db.Orders.Select(o=>varq=db.Products.Average(p=>varcategoriesfrompingrouppbyp.CategoryIDintoselectnew ExpensiveProducts fromp2in wherep2.UnitPrice>g.Average(p3=> select LINQtoSQL(4說明:在Join操作中,分別為Join(Join查詢SelectMany(Select一對多選擇)和GroupJoin(Join查詢)。該擴(kuò)展innerjoin操作說明:我們在寫查詢語句時,如果被翻譯成SelectMany2個條件。1join和into,2:必須出現(xiàn)EntitySet。在我們表關(guān)系中有一對一關(guān)系,一對多關(guān)系,多對多關(guān)系等,下面分別介紹一下。1.一對多關(guān)系(1tovarqfromcinfromoinwherec.City==select語句描述:語句描述:Customers與OrdersOrders在Customers類中以EntitySetfrom是從c.Ordersdb.OrdersFromvarqfrompinwherep. r.Country=="USA"&&p.UnitsInStock==selectr表。這個例子在Where選其供應(yīng)商 且缺貨的產(chǎn)品。生成SQL語句為SELECT[t0].[ProductID], ],[t0].[UnitPrice],[t0].[UnitsInStock],d]FROM[dbo].[Products]AS[t0]LEFTOUTERJOIN rs]AS[t1]ON rID] rID]WHERE([t1].[Country]=@p0)([t0].[UnitsInStock]=@p1)--@p0:InputNVarChar(Size=3;Prec=0;Scale=0)[USA]--@p1:InputInt(Size=0;Prec=0;Scale=0)2.多對多關(guān)系(Manyto2.多對多關(guān)系(Manytovarqfromeinfrometinwheree.City==select 說明:多對多關(guān)系一般會涉及三個表(說明:多對多關(guān)系一般會涉及三個表(2個表)Employees,EmployeeTerritoriesTerritories1:M:1。Employees和Territories沒有很明確的關(guān)系。語句描述:這個例子在FromSQLSELECT[t0].[FirstName],[t0].[LastName],[t2].[TerritoryDescription]FROM[dbo].[Employees]AS[t0]CROSSJOIN[dbo].[EmployeeTerritories]AS[t1]INNERJOIN[dbo].[Territories]AS[t2]ON[t2].[TerritoryID]=[t1].[TerritoryID]WHERE([t0].[City]=@p0)AND([t1].[EmployeeID]=[t0].[EmployeeID])--@p0:InputNVarChar(Size=7;Prec=0;Scale=0)[Seattle]varqfrome1infrome2inwheree1.City==selectnew FirstName1=e1.FirstName,LastName1= FirstName2=e2.FirstName,LastName2= selectselect子句中使用外鍵導(dǎo)航篩選成對的雇員,每對中一個雇員隸屬于另一個雇員,且兩個雇員都來自相同城市。生成SQL語句為:SELECT[t0].[FirstName]AS[FirstName1],[t0].[LastName]AS[LastName1],[t1].[FirstName]AS[FirstName2],[t1].[LastName]AS[LastName2],[t0].[City]FROM[dbo].[Employees]AS[t0],[dbo].[Employees]AS[t1]WHERE([t0].[City]=[t1].[City])AND([t1].[ReportsTo]=joinintoSelectManyjoinintoGroupJoin。在這里into的概念是對其結(jié)果進(jìn)行重新命名。1.雙向聯(lián)接(Twowayvarqfromcinjoinoindb.Ordersonequalso.CustomerIDintoselect OrderCount=11c(fromcindb.Customers),Manyjoinoindb.Ordersc,就會有一組o,那這一組oorderso命名內(nèi)嵌的T-SQL返回值作為字段值。如圖所示:生成SQLSELECT[t0].[ContactName],SELECTFROMFROM[dbo].[Orders]ASWHEREWHERE[t0].[CustomerID]=)AS[OrderCount]FROM[dbo].[Customers]AS2.三向聯(lián)接2.三向聯(lián)接(Therewayvarqfromcinjoinoindb.Ordersonequalso.CustomerIDintojoineindb.Employeesonequalse.Cityintoselect ords= emps=生成SQL生成SQLSELECT[t0].[ContactName],SELECTFROM[dbo].[Orders]ASWHERE[t0].[CustomerID]=)AS[ords],(SELECTFROM[dbo].[Employees]ASWHERE[t0].[City]=)AS[emps]FROM[dbo].[Customers]AS3.左外部聯(lián)接(Left3.左外部聯(lián)接(LeftOuterDefaultIfEmpty()varqfromeinjoinoindb.Ordersoneequalso.Employeeintofromoinselect Order=說明:以Employees左表,說明:以Employees左表,Orders右表,Ordersnull值填充。Joinords,使用DefaultIfEmpty()Orderfromoinords.DefaultIfEmpty()ords組再一次遍歷,所以,最后結(jié)果中的Orderfromoinords.DefaultIfEmpty()這句,selectselectnew{e.FirstName,e.LastName,Order=ords}Order就是一個集合。4.Let(Projectedlet說明:let語句是重命名。let位于第一個from和select語句之間。varqfromcinjoinoindb.Ordersonequalso.CustomerIDintoletz=c.City+fromoinselect 5.組合鍵5.組合鍵(Compositevarqfromoinfrompinjoindin on } intofromdinselect 6.null/null(Nullable/NonnullableKey這個實(shí)例顯示如何構(gòu)造一側(cè)可為null而另一側(cè)不可為nullvarqfromoinjoinein ono.EmployeeID (int?)e.EmployeeIDintofromeinselect LINQLINQtoSQL(5Order的擴(kuò)展方法是OrderBy和OrderByDescending這個例子使用orderbyvarqfromeinorderbyselect注意:Where和OrderByT-SQL中,Where和OrderByvarqfromoinwhereo.ShipCity==orderbyselectwhereorderbyvarqfrompinorderbyp.UnitPriceselect語句描述:使用復(fù)合的orderbyvarqfromcinorderbyc.City,select說明:按多個表達(dá)式進(jìn)行排序,例如先按說明:按多個表達(dá)式進(jìn)行排序,例如先按City排序,當(dāng)City相同時,按ContactNameLambda表達(dá)式像varq.OrderBy(c=>.ThenBy(c=>在在T-SQL中沒有ThenByOrderByvarq.OrderBy(c=>.OrderBy(c=>所要注意的是,多個所要注意的是,多個OrderByvarq.OrderByDescending(c=>.ThenByDescending(c=>varvarq.OrderBy(c=> 會被拋出異常。錯誤是前面的操作 需要說明的是,OrderBy操作,不支持按type排序,也不支 類。比varq.Select(c=>{{ .OrderBy(c=>如果你想使用OrderBy(c如果你想使用OrderBy(cc)C#語言的基本類型。比如下句,這里Citystring類型。varq.Select(c=>.OrderBy(c=>這兩個擴(kuò)展方式都是用在OrderBy/OrderByDescending之后的,第一個ThenBy/ThenByDescending擴(kuò)展方法作為第二位排序依據(jù),第二個ThenBy/ThenByDescending則作為第三位排序依據(jù),以此類推varqfromoinwhereo.EmployeeID==orderbyo.ShipCountry,o.Freightselectorderbyorderby先按發(fā)往國家再按運(yùn)費(fèi)從高到低的順序?qū)mployeeID1varqfrompingrouppbyp.CategoryIDintoorderbyselectnew MostExpensiveProducts fromp2in wherep2.UnitPrice==g.Max(p3=> selectorderby、Max和GroupBy得出每種類別中單價最高的產(chǎn)品,并按CategoryID對這組產(chǎn)品進(jìn)行排LINQtoSQL(6Groupvarqfrompingrouppbyp.CategoryIDintoselect語句描述:使用語句描述:使用GroupBy按CategoryID說明:frompindb.Products表示從表中將產(chǎn)品對象取出來。grouppbyp.CategoryIDintog表示對p按CategoryID字段歸類。其結(jié)果命名為g,一旦重新命名,pselectselectg。當(dāng)varqfrompingrouppbyforeach(vargpin{if(gp.Key== foreach(varitemin //do } varqfrompingrouppbyp.CategoryIDintoselectnew{CategoryID=g.Key,g說明:在這句說明:在這句LINQ語句中,有2個property:CategoryID和g。這個 把g的property封裝成一個完整的分組。如下圖所示:如果想遍歷 類中所有記錄,要這么做foreach(vargpin{if(gp.CategoryID== foreach(varitemin }}//do}}}varqfrompingrouppbyp.CategoryIDintoselectnew MaxPrice=g.Max(p=>語句描述:使用Group語句描述:使用GroupByMaxCategoryID說明:先按CategoryIDProductsCategoryID值,并把UnitPricevarqfrompingrouppbyp.CategoryIDintoselectnew MinPrice=g.Min(p=>語句描述:使用Group語句描述:使用GroupByMinCategoryID說明:先按CategoryIDProductsCategoryID值,并把UnitPricevarqfrompingrouppbyp.CategoryIDintoselectnew AveragePrice=g.Average(p=>語句描述:使用Group語句描述:使用GroupByAverageCategoryID說明:先按CategoryID歸類,取出CategoryIDvarqfrompingrouppbyp.CategoryIDintoselectnew TotalPrice=g.Sum(p=>語句描述:使用Group語句描述:使用GroupBy和SumCategoryID說明:先按CategoryID歸類,取出CategoryIDvarqfrompingrouppbyp.CategoryIDintoselectnew NumProducts=語句描述:使用Group語句描述:使用GroupBy和CountCategoryID中產(chǎn)品的數(shù)量。說明:先按CategoryID歸類,取出CategoryIDvarqfrompingrouppbyp.CategoryIDintoselectnew NumProducts NumProducts=g.Count(p=>)語句描述:使用Group語句描述:使用GroupBy和CountCategoryID說明:先按CategoryID歸類,取出CategoryIDCountLambda表達(dá)式,Lambda表達(dá)式中的p,代表這個組里的一個元素或?qū)ο?,即某一個產(chǎn)品。varqfrompingrouppbyp.CategoryIDintowhereg.Count()>=selectnew ProductCount=語句描述:根據(jù)產(chǎn)品的―ID語句描述:根據(jù)產(chǎn)品的―ID10的ID和產(chǎn)品數(shù)量。這個示例在GroupBy子句后使用Where子句10種產(chǎn)品的類別。說明:在翻譯成SQLWhere10.多列(Multiplevarcategoriesfrompingrouppby }}intointo select 語句描述:使用Group語句描述:使用GroupBy按CategoryIDrID說明:既按產(chǎn)品的分類,又按供應(yīng)商分類。在by后面,new出來一 類。這里,Key其實(shí)質(zhì)是一個類的對象,Key含兩個Property:CategoryID rID。用g.Key.CategoryID可以遍歷CategoryID的值varcategoriesfrompingrouppbynew{Criterion=p.UnitPrice>10}intoselect語句描述:使用語句描述:使用GroupBy1010LINQtoSQL(7說明:用于判斷集合中是否有元素滿足某一條件;不延遲。(True,否則為False)。2種形式,分別為簡單形式和帶條件形式。varqfromcinwhereselect生成SQL生成SQLSELECT[t0].[CustomerID],[t0].[ [t0].[ContactName],[t0].[ContactTitle],[t0].[Address],[t0].[City],[t0].[Country],[t0].[Phone],[t0].[Fax]FROM[dbo].[Customers]AS[t0]WHERENOT(EXISTS(SELECTNULLAS[EMPTY]FROM[dbo].[Orders]ASWHERE[t1].[CustomerID]=varqfromcinwherec.Products.Any(p=>)select生成SQL生成SQLSELECT[t0].[CategoryID],[t0].[CategoryName],[t0].[Description],[t0].[Picture]FROM[dbo].[Categories]AS[t0]WHEREEXISTS(SELECTNULLAS[EMPTY]FROM[dbo].[Products]ASWHERE ]=1)([t1].[CategoryID]=varqfromcinwherec.Orders.All(o=>o.ShipCity==selectstring[]customerID_Setnewstring[]{"AROUT","BOLID","FISSA"};varq=fromoinwhereselect語句描述:查找語句描述:查找"AROUT","BOLID"和"FISSA"LINQtoSQL中使用ContainsCustomerIDCustomerIDinLINQtoSQL語句里。比如:varq=fromoinwherenewstring[]{"AROUT","BOLID","FISSA"selectNotNotContainsvarq=fromoinwherenewstring[]{"AROUT","BOLID","FISSA"selectvarorder=(fromoin whereo.OrderID== selecto).First();varq==>p.Orders.Contains(order)).ToList();foreach(varcustinq){foreach(varordin //do }string[]citiesnewstring[]{"Seattle","London","Vancouver","Paris"};varq=語句描述:這個例子使用Contains語句描述:這個例子使用ContainsLINQtoSQL(8varq= fromcin select fromcin select fromein select 語句描述:返回所有消費(fèi)者和雇員 和傳真語句描述:返回所有消費(fèi)者和雇員 和傳真varq= fromcin select Name }} fromein select Name=e.FirstName+""+ Phone= varvarq= fromcin select fromein select 語句描述:返回所有消費(fèi)者和雇員 varq= fromcin select fromein select varvarq= fromcin select fromein select LINQtoSQL(9Top/BottomPaging說明:獲取集合的前nvarq=fromeinorderbyselect5說明:跳過集合的前nvarq=frompinorderbyp.UnitPriceselect10將在返回false或源序列的末尾結(jié)束。斷返回false,接下來將不再進(jìn)行判斷并返回剩下的所有元素。適用場景:結(jié)合Skip和Takevarq=fromcinorderbyselect語句描述:使用Skip和Take5010Products6頁的數(shù)據(jù)。varq=frompinwherep.ProductID>orderbyselect語句描述:使用Where子句和Take505ProductID)ProductID,然后按ProductID10個結(jié)果,因此提供Products6LINQtoSQL語句中,為我們提供了SqlMethodsLike方法用于自定義通配表達(dá)式,Equals用于相比較是否相等。圍區(qū)間的一個字符。比如查詢消費(fèi)者ID以“C”開頭的消費(fèi)者。varq=fromcin whereSqlMethods.Like(c.CustomerID, select比如查詢消費(fèi)者ID沒有“AXOXT”varq=fromcin where!SqlMethods.Like(c.CustomerID, selectvarq=fromoin where .DateDiffDay(o.OrderDate,o.ShippedDate)< select語句描述:查詢在創(chuàng)建訂單后的10已編譯查詢操作(Compiled說明:在之前我們沒有好的方法對寫出的SQL 創(chuàng) piledontextdb=newfn ontextdb2,stringcity)fromcinwherec.City==selectc);//2.London的消費(fèi)者,LonCustsvarLonCusts"London");//3.SeattlevarSeaCustsfn(db,"Seattle");LINQtoSQL(10說明:new一個對象,使用InsertOnSubmit方法將其加入到對應(yīng)的集合中,使用SubmitChanges() ontextdb=newNorthwindD newCustomer=newCustomer{CustomerID=NameName=ContactName="JohnContactTitle="SalesAddress= Way",City=Region=PostalCode=Country=Phone="(425)555-Fax=語句描述:使用InsertOnSubmitCustomers表對象。調(diào)用SubmitChanges將此新Customer保說明:Category與ProductCategory(一端)的數(shù)據(jù)時,LINQtoSQL會自動將Product(多端)的varnewCategory=new{CategoryName=Description="Widgetsarethe};varnewProduct=new{ProductName="BlueUnitPrice=Category=語句描述:使用語句描述:使用InsertOnSubmitCategories表中,并將新ProductCategory表中。調(diào)用varnewEmployee=new{FirstName=LastName=};varnewTerritory=new{TerritoryID=TerritoryDescription=Region=};varnewEmployeeTerritory=new{Employee=Territory=語句描述:使用InsertOnSubmitEmployees表中,將新TerritoryTerritories表中,并將新EmployeeTerritory對象添加到與此新Employee對象和新TerritoryEmployeeTerritories表中。調(diào)用SubmitChanges將這些新對象及其關(guān)系保持到數(shù)據(jù)庫。CUDOverrideusingDynamic說明:CUDCreate、Update、Delete的縮寫。下面的例子就是新建一個ID(主鍵)32Region,不考慮數(shù)據(jù)庫中有沒有ID32的數(shù)據(jù),如果有則替換原來的數(shù)據(jù),沒有則插入。RegionnwRegion=new{RegionID=RegionDescription=語句描述:使用D ontext提供的分部方法InsertRegion插入一個區(qū)域。對SubmitChanges的調(diào)用調(diào)用InsertRegion重寫,后者使用動態(tài)CUD運(yùn)行LinqToSQL生成的默認(rèn)SQL查詢。LINQtoSQL(11 ontext中,對于不同 ontext中,對于不同的 ontex看下面的講解Customercustdb.Customers.First(c=>c.CustomerID=="ALFKI");cust.ContactTitle="Vice 語句描述:使用SubmitChangesCustomervarq=frompin wherep.CategoryID== selectp;foreach(varpin{p.UnitPrice+=}語句描述:使用SubmitChangesLINQtoSQL(12DeleteOrderDetailorderDetail(c=>c.OrderID==10255&&c.ProductID==36);語句描述:使用語句描述:使用DeleteOnSubmit方法從OrderDetail表中刪除OrderDetail對象。調(diào)用SubmitChanges說明:Order與OrderDetailDeleteOnSubmit其OrderDetail(多端)DeleteOnSubmit其varorderDetailsfromoinwhereo.Order.CustomerID=="WARTH"o.Order.EmployeeID==selecto;varorder(fromoin whereo.CustomerID=="WARTH"&&o.EmployeeID== selecto).First();foreach(OrderDetailodin{}DeleteOnSubmitOrder和OrderDetailsOrder和OrderDetail對象。首先從OrderDetails刪除,然后從OrdersSubmitChanges將此刪除保持到數(shù)據(jù)庫。推理刪除(Inferred說明:Order與OrderDetailCustomerIDWARTH和EmployeeID為3的數(shù)據(jù),那么我們不須全部刪除呢?例如Order的OrderID10248的OrderDetail有很多,但是我們只要刪除ProductID11的OrderDetailRemove方法。Orderorder=db.Orders.First(x=>x.OrderID==10248);OrderDetailod=order.OrderDetails.First(d=>d.ProductID==11); 實(shí)體將該對象從其EntitySet中移除時,推理刪除如何導(dǎo)致在該對象上發(fā)生實(shí)際的刪除操作。僅當(dāng)實(shí)體的關(guān)聯(lián)映射將DeleteOnNull設(shè)置為true且CanBeNull為false時,才會發(fā)生推理刪除Attach(Updatewith ontext中,查詢出Customer和Order,在另一個 ontext中,Customer ontext中,查詢出Customer和Order,在另一個 ontext中,Customer的地址123FirstAve,Order的CustomerID更新為CHOPS//XML來獲取要附加的實(shí)體//CustomerList<Order>deserializedOrders=newCustomerdeserializedC1;using(NorthwindD tempdb=newNorthwindD {c1=tempdb.Customers.Single(c=>c.CustomerID==deserializedC1=new Address= City=NameName ContactName= ContactTitle= Country= CustomerID= Fax= Phone= PostalCode= Region=Customertempcust tempdb.Customers.Single(c=>c.CustomerID==foreach(Orderoin deserializedOrders.Add(new CustomerID= EmployeeID=FreightFreight= OrderDate= OrderID= RequiredDate= ShipAddress= ShipCity= ShipName= ShipCountry= ShippedDate= ShipPostalCode= ShipRegion= ShipVia= }using(NorthwindD ontextdb2=new { 更//Customer更新,不能寫錯 的實(shí)deserializedC1.Address="123First//附加訂單列表中的所有實(shí)體foreach(Orderoin o.CustomerID= }Attach(UpdateandDeletewith說明:在不同的 ontext中,實(shí)現(xiàn)插入、更新、刪除??聪旅娴囊粋€例子LoadWith在一個查詢中預(yù)先加載客戶和訂單,//Customercust=null;using(NorthwindD ontexttempdb=newNorthwindD {DataLoadOptionsshape=newshape.LoadWith<Customer>(c=>tempdb.LoadOptions=tempdb.DeferredLoadingEnabled=cust=tempdb.Customers.First(x=>x.CustomerID==}OrderorderA=OrderorderB=cust.Orders.First(x=>x.OrderID>orderA.OrderID);using(NorthwindD ontextdb2=new { 更 ;否則將在提交時插入它c(diǎn)ust.Phone="2345orderA.ShipCity= OrderorderC=newOrder(){ShipCity="NewYork" }語句描述:從一個上下文提取實(shí)體,并使用Attach和AttachAll附加來自其他上下文的實(shí)體,然后更新這兩個實(shí)體,刪LINQtoSQL(13下表介紹LINQtoSQL兩個或用戶同時嘗試更新同一數(shù)據(jù)庫行的情形突兩個或用戶同時嘗試向一行的一列或多列提交值的情形用于解決并發(fā)的技術(shù)制先其他事務(wù)是否已更改了行中的值,再允許提交更改的技術(shù)。相比之下,保守式并發(fā)控制則是通過鎖定記錄來避免發(fā)生并發(fā)。之所以稱作通過重新查詢數(shù)據(jù)庫刷新出現(xiàn)的項(xiàng),然后協(xié)調(diào)差異的過程。刷新對象時,LINQtoSQL更改會保留以下數(shù)據(jù):最初從數(shù)據(jù)庫獲取并用于更新檢查的值通過后續(xù)查詢獲得的新數(shù)據(jù)庫值。 LINQtoSQL隨后解會確定相應(yīng)對象是否發(fā)生(即它的一個或多個成員值是否已發(fā)生決改)。如果此對象發(fā)生,LINQtoSQL下一步會確定它的哪些成員生。LINQtoSQL發(fā)現(xiàn)的任何成員都會添加到列表中在LINQtoSQL對象模型中,當(dāng)以下兩個條件都得到滿足時,就會發(fā)生“開放式并 ”:客戶端嘗試向數(shù)據(jù)庫提交改;數(shù)據(jù)庫中的一個或多個更新檢查值自客戶端上改;數(shù)據(jù)庫中的一個或多個更新檢查值自客戶端上 它們以來已得到更新。 的解決過程包括查明對象的哪些成發(fā) ,然后決定您希望如何進(jìn)行處理開放式并發(fā)(Optimistic說明:這個例子中在說明:這個例子中在 數(shù)據(jù)之前,另外一個用戶已經(jīng)修改并提交更新了這個數(shù)據(jù),所以不會出 ontextotherUser_db=new ontext();varotherUser_product=otherUser_db.Products.First(p=>p.ProductID==1);otherUser_product.UnitPrice=999.99M;otherUser_db.SubmitChanges();//varproductdb.Products.First(p=>p.ProductID==1);product.UnitPrice=777.77M;try{db.SubmitChanges();//當(dāng)前連接執(zhí)行成功}catch {}說明:我說明:我 數(shù)據(jù)之后,另外一個用戶獲取并提交更新了這個數(shù)據(jù),這時,我們更新這個數(shù)據(jù)時,引起了一個并 。//varproductdb.Products.First(p1);// ontextotherUser_db=new ontext();varotherUser_product=otherUser_db.Products.First(p=>p.ProductID==1);otherUser_product.UnitPrice=999.99M;product.UnitPrice={}catch {}LINQtoSQL顯式本地事務(wù):調(diào)用SubmitChanges顯式本地事務(wù):調(diào)用SubmitChanges時,如果Transaction屬性設(shè)置為事務(wù),則在同一事務(wù)的上下文中執(zhí)行xt的連接匹配。如果使用其他連接,則 異常ubmitChanges調(diào)用。成功執(zhí)行事務(wù)后,要由您來提交或回滾事務(wù)。與事務(wù)對應(yīng)的連接必須與用于構(gòu)造xt的連接匹配。如果使用其他連接,則 異常顯式可分發(fā)事務(wù):可以在當(dāng)前Transaction顯式可分發(fā)事務(wù):可以在當(dāng)前Transaction的作用域中調(diào)用LINQtoSQLAPI(包括但不限于es)。LINQtoSQL檢測到調(diào)用是在事務(wù)的作用域內(nèi),因而不會創(chuàng)建新的事務(wù)。在這種情況下,<token>vbtecdlinq</token>還會避免關(guān)閉連接。您可以在此類事務(wù)的上下文中執(zhí)行查詢和SubmitChanges操作。隱式事務(wù):當(dāng)您調(diào)用SubmitChanges隱式事務(wù):當(dāng)您調(diào)用SubmitChanges時,LINQtoSQL會檢查此調(diào)用是否在TransactionTransaction屬性是否設(shè)置為由用戶啟動的本地事務(wù)。如果這兩個事務(wù)它均未找到,則LINQtoSQL啟動本地事務(wù),并使用此事務(wù)執(zhí)行所生成的SQL命令。當(dāng)所有SQL命令均已成功執(zhí)行完畢時,LINQtoSQL提交本地說明:這個例子在執(zhí)行SubmitChanges()操作時,隱式地使用了事務(wù)。因?yàn)樵诟?種產(chǎn)品的庫存數(shù)量時,第二個產(chǎn)品庫存 了服務(wù)器上的CHECK約束。這導(dǎo)致了更新產(chǎn)品全部失敗了,系統(tǒng)回滾到這個操作的初始狀態(tài)。{Productprod1=db.Products.First(p=>p.ProductID==Productprod2=db.Products.First(p=>p.ProductID==prod1.UnitsInStock-=prod2.UnitsInStock5;//錯誤: }catch .SqlException{}說明:這個例子使用顯式事務(wù)。通過在事務(wù)中加入對數(shù)據(jù)說明:這個例子使用顯式事務(wù)。通過在事務(wù)中加入對數(shù)據(jù) 以防止出現(xiàn)開放式并發(fā)異常,顯式事務(wù)可以提 的保護(hù)如同上一個查詢中,更新prod2的UnitsInStock字段將使該字段為負(fù)值,而 了數(shù)據(jù)庫中的CHECK約束。這using(TransactionScopets=new{ Productprod1=db.Products.First(p=>== Productprod2=db.Products.First(p=>== prod1.UnitsInStock-= prod2.UnitsInStock5;//錯誤:庫存數(shù)量的單位不能是負(fù)數(shù)catch .SqlException }LINQtoSQL(14NullReportsToEmployeenullNullable<T>.HasValue查詢雇員,Nullable<T>.ValueReportsToEmployeenull的雇員的ReportsTo的值。varqfromeinwheree.ReportsToEmployee==selectvarqfromeinwhereselect返回前者的EmployeeID編號。請注意.Valuevarqfromeinwhereselect ReportsTo=LINQtoSQLDateTime方法。但是,SQLServer和CLRDateTime類型在范圍和計(jì)時周期精度上不同,如0001年119999年1231100毫微秒(0.T-SQL1753年119999年12313.33…毫秒(0. 日 月日1分鐘(60秒CLRCLRDateTime類型與SQLServerSQLServer的數(shù)據(jù)用CLR時,絕不會損失量值或精度。但如果反過來的話,則范圍可能會減小,精度可能會降低;時,絕不會損失量值或精度。但如果反過來的話,則范圍可能會減小,精度可能會降低;SQLServer日期不存在概念,而在概念,而在CLRLINQtoSQL查詢使用以當(dāng)?shù)貢r間、UTCvarqfromoinwhereo.OrderDate.Value.Year==selectDateTime的Year1997varqfromoinwhereo.OrderDate.Value.Month==selectDateTimeMonthvarqfromoinwhereo.OrderDate.Value.Day==selectDateTimeDay屬性查找某月31LINQtoSQL(15LINQtoSQL支持以下StringSystem.StringSQL則不區(qū)分大小字符串串聯(lián)(Stringvarqfromcinselect Location=c.City+","+varqfrompinwherep.ProductName.Length<selectLength10varqfromcinwhereselect語句描述:這個例子使用Contains方法查找所有其聯(lián)系 varqfromcinselect SpacePos=c.ContactName.IndexOf("語句描述:這個例子使用IndexOf方法查找每個客戶聯(lián)系 中出現(xiàn)第一個空格的位置varqfromcinwhereselect語句描述:這個例子使用StartsWith方法查找聯(lián)系 varqfromcinwhereselect語句描述:這個例子使用EndsWith方法查找聯(lián)系 varqfrompinselect語句描述:這個例子使語句描述:這個例子使用Substring方法返回產(chǎn)品名稱中從 母開始的部分String.Substring(start,varqfromeinwheree.HomePhone.Substring(6,3)==select語句描述:這個例子使語句描述:這個例子使用Substring方法查找家 varqfromeinselect LastName= 語句描述:這個例子使用ToUpper方法返回姓氏已轉(zhuǎn)換為大寫的雇 varqfromcinselect語句描述:這個例子使用ToLowervarqfromeinselecte.HomePhone.Substring(0,語句描述:這個例子使語句描述:這個例子使用Trim方法返回雇員家 的前五位,并移除前導(dǎo)和尾隨空格String.Insert(pos,varqfromeinwheree.HomePhone.Substring(4,1)==selecte.HomePhone.Insert(5,語句描述:這個例子使語句描述:這個例子使用Insert方法返回第五位為)的雇 的序列,并在)后面插入一個:varqfromeinwheree.HomePhone.Substring(4,1)==select語句描述:這個例子使用Remove方法返回第五位為)的雇 的序列,并移除從第十個字符開始的所有字符String.Remove(start,varqfromeinwheree.HomePhone.Substring(4,1)==selecte.HomePhone.Remove(0,語句描述:這個例子使用Remove語句描述:這個例子使用Remove方法返回第五位為)的雇 的序列,并移除前六個字符 ce(find, varqfromsin select Country= ce("UK","United ce("USA","UnitedStatesof語句描述:這個例子使用Re ce方法返回Country字段中UK被替換為UnitedKingdom以及USA被替換為UnitedStatesofAmerica的供應(yīng)商信息。LINQtoSQL(16運(yùn)行庫中的對象具有唯一標(biāo)識運(yùn)行庫中的對象具有唯一標(biāo)識 同一對象的兩個變量實(shí)際上 此對象的同一實(shí)例。你更改一個變量后,可實(shí)際上,通常我們是將數(shù)據(jù)從數(shù)據(jù)庫中提取出來放入另一層中,應(yīng)用程序在該層對數(shù)據(jù)進(jìn)行處理。這就是實(shí)際上,通常我們是將數(shù)據(jù)從數(shù)據(jù)庫中提取出來放入另一層中,應(yīng)用程序在該層對數(shù)據(jù)進(jìn)行處理。這就是LINQto 對于對象。你期望在你反復(fù)向 ontext索取相同的信息時,它實(shí)際上會為你提供同一對象實(shí)例。你將它們設(shè)計(jì)層次結(jié)構(gòu)或關(guān)系圖。你希望像檢索實(shí)物一樣檢索它們,而不希望僅僅因?yàn)槟愣啻嗡饕粌?nèi)容而收到大量層次結(jié)構(gòu)或關(guān)系圖。你希望像檢索實(shí)物一樣檢索它們,而不希望僅僅因?yàn)槟愣啻嗡饕粌?nèi)容而收到大量 實(shí)例 在LINQtoSQL中,D ontext管理對象標(biāo)識。只要你從數(shù)據(jù)庫中檢索新行,該行就會由其主鍵記錄到標(biāo)識表 ontext將數(shù)據(jù)庫看到的標(biāo)識(即主鍵)的概念轉(zhuǎn)換成相應(yīng)語言看到的標(biāo)識(即實(shí)例)的概念。應(yīng)用程序只看到處于第一次檢索時的狀態(tài)LINQtoSQL使用此方法來管理本地對象的完整性,以支持開放式更新。由于在最初創(chuàng)建對象后唯一發(fā)生的更改是由應(yīng)用程序做出的,因此應(yīng)用程序的意向是很明確的。如果在中間階段外部某一方做了更改,則在調(diào)用SubmitChanges()時 以上來自在第一個示例中,如果我們執(zhí)行同一查詢兩次,則每次都會收到對內(nèi)存中同一對象 。很明顯,cust1和cust2是同一對對 Customercust1=db.Customers.First(c=>c.CustomerID==Customercust2=db.Customers.First(c=>c.CustomerID==下面的示例中,如果您執(zhí)行返回?cái)?shù)據(jù)庫中同一行的不同查詢,則您每次都會收到對內(nèi)存中同一對象 。cust1和cust2同一個對同一個對 ,但是數(shù)據(jù)庫查詢了兩次Customercust1=db.Customers.First(c=>c.CustomerID==Customercust2=fromoinwhereo.Customer.CustomerID==selectoLINQtoSQL(17使用延遲加載將額外信息的檢索操作使用延遲加載將額外信息的檢索操作 這個這個ID查詢出OrderIDvarcusts fromcin wherec.City=="Sao selectc;//上面的查詢句法不會導(dǎo)致語句立即執(zhí)行,性的語句,foreach(varcustin{foreach(varordin 和訂單數(shù) }語句描述:原始查詢未請求數(shù)據(jù),在所檢索到各個對象 中導(dǎo)航如何能導(dǎo)致觸發(fā)對數(shù)據(jù)庫的新查詢預(yù)先加載:LoadWith 你如果想要同時查詢出一些對象的集合的方法。LINQtoSQL提供了DataLoadOptions用于立即加載對象。方法包括:LoadWith方法,用于立即加載與主目標(biāo)相關(guān)的數(shù)據(jù)。AssociateWith方法,用于篩選為特定關(guān)系檢索到的對象。 使用LoadWith方法指定應(yīng)同時檢索與主目標(biāo)相關(guān)的哪些數(shù)據(jù)。例如,如果你知道你需要有關(guān)客戶的訂單的信息,則可以使用LoadWith來確保在檢索 下面的示例中,我們通過設(shè)置DataLoadOptions,來指示D ontext在加載Customers的同時把對應(yīng)的Orders一起加載,在執(zhí)行查詢時會檢索位于SaoPaulo的所有Customers的所有Orders。這樣一來,連續(xù) Customer對象的Orders屬性不會觸發(fā)新的數(shù)據(jù)庫查詢。在執(zhí)行時生成的SQL語句使用了左連接。 ontextdb=newNorthwindD DataLoadOptionsds=newDataLoadOptions();ds.LoadWith<Customer>(p=>p.Orders);db.LoadOptions=ds;varcusts= fromcin wherec.City=="Sao selectc);foreach(varcustin{foreach(varordin{{ ine("CustomerID{0}hasan }語句描述:在原始查詢過程中使用LoadWith請求相關(guān)數(shù)據(jù),以便稍后在檢索到的各個對象中導(dǎo)航時不需要對數(shù)據(jù)庫進(jìn)行額 使用AssociateWith方法指定子查詢以限制檢索的數(shù)據(jù)量。在下面的示例中,AssociateWith方法將檢索的Orders限制為當(dāng)天尚未裝運(yùn)的那些Orders。如果沒有此方法,則會檢索所有Orders,即使只需要一個子集。但是生成SQL語句會發(fā)現(xiàn)生成了很多SQL語句。ontextontextdb2=newDataLoadOptionsds=newDataLoadOptions(); p=>p.Orders.Where(o=>o.ShipVia>1));db2.LoadOptions=ds;varcusts= fromcin wherec.City== selectc;foreach(varcustin{foreach(varordin foreach(varorderDetailin //cust.CustomerIDord.OrderID, }語句描述:原始查詢未請求數(shù)據(jù),在所檢索到各個對象語句描述:原始查詢未請求數(shù)據(jù),在所檢索到各個對象 中導(dǎo)航如何以觸發(fā)對數(shù)據(jù)庫的新查詢而告終。此示例還說明在遲加載關(guān)系對象時可以使用AssoicateWithLoadWith方法來確保在檢索的同時檢索訂單信息,在檢索訂單信息的同時檢索訂單詳細(xì)AssociateWith方法來限制訂單詳細(xì)信息的排序規(guī)ontextontextdb2=newDataLoadOptionsds=newDataLoadOptions();ds.LoadWith<Customer>(p=>p.Orders);ds.LoadWith<Order>(p=>p.OrderDetails); p=>p.OrderDetails.OrderBy(o=>o. db2.LoadOptions=ds;varcusts=( fromcin wherec.City== selectc);foreach(varcustin{foreach(varordin foreach(varorderDetailin //cust.CustomerID }語句描述:在原始查詢過程中使用LoadWith請求相關(guān)數(shù)據(jù),以便稍后在檢索到的各個對象中導(dǎo)航時此示例還說明在急切加載關(guān)系對象時可以使用AssoicateWith對它們進(jìn)行排序。這個例子在CategoryLoadProducts分部方法。當(dāng)產(chǎn)品的類別被加載的時候,就直接優(yōu)先調(diào)用了LoadProducts方法來查詢沒有貨源的產(chǎn)品。privateIEnumerable<Product>LoadProducts(Category{//LINQtoSQLLoadProducts 過程也可以return .Where(p=>p.CategoryID== .Where(p=> }ontextontextdb2=newDataLoadOptionsds=newDataLoadOptions();ds.LoadWith<Category>(p=>p.Products);db2.LoadOptions=ds;varq=( fromcin wherec.CategoryID< selectc);foreach(varcatin{foreach(varprodin //查詢cat.CategoryID, }語句描述:重寫Category類中的分部方法LoadProducts。加載某種類別的產(chǎn)品時,調(diào)用LoadProducts以加載此類LINQtoSQL(18AsEnumerable 使用AsEnumerable<TSource>可返回類型化為泛型IEnumerable的參數(shù)。在此示例中,LINQtoSQL(使用默認(rèn)泛型Query)會嘗試將查詢轉(zhuǎn)換為SQL并在服務(wù)器上執(zhí)行。但where子句 (isValidProduct),此方法無法轉(zhuǎn)換為SQL。解決方法是指定where的客戶端泛型IEnumerable<T>實(shí)現(xiàn)以替換泛型IQueryable<T>??赏ㄟ^調(diào)用AsEnumerable<TSource>運(yùn)算符來執(zhí)行此操作。varqfrompinwhereselect語句描述:這個例子就是使用AsEnumerable以便使用Where的客戶端IEnumerable實(shí)現(xiàn),而不是默認(rèn)的IQueryable將在服務(wù)器上轉(zhuǎn)換為SQL并執(zhí)行的默認(rèn)Query<T>實(shí)現(xiàn)。這很有必要,因?yàn)閃here子句 isValidProduct,該方法不能轉(zhuǎn)換為SQL。使用ToArray<TSource>varqfromcinwherec.City==selectCustomer[]qArray=語句描述:這個例子使用ToArray使用ToList<TSource>可從序列創(chuàng)建泛型列表。下面的示例使用ToList<TSource>varqfromeinwheree.HireDate>=newDateTime(1994,1,selectList<Employee>qList= 使用Enumerable.ToDictionary<TSource,TKey>方法可以將序列轉(zhuǎn)化為字典。TSourcesource中的元素的類型;TKey表示keySelectorDictionary<TKey,TValue>。varqfrompinwherep.UnitsInStock<=p.ReorderLevel&&!p.Dis selectDictionary<int,Product>qDictionaryq.ToDictionary(p=>p.ProductID);foreach(intkeyin{ }}語句描述:這個例子使用ToDictionary將查詢和鍵表達(dá)式直接鍵表達(dá)式直接計(jì)算為Dictionary<K,T>LINQtoSQL(19ADO.NETLINQto它基于由ADO.NET提供程序模型提供的服務(wù)。因此,我們可以將LINQtoSQL代碼與現(xiàn)有的ADO.NET應(yīng)用程序混合在一起,將當(dāng)前ADO.NET解決方案遷移到LINQtoSQL。 在創(chuàng)建LINQtoSQLD ontext時,可以提供現(xiàn)有ADO.NET連接。對D ontext的所有操作(包括查詢)都使用所提供的這個連接。如果此連接已經(jīng)打開,則在您使用完此連接時,LINQtoSQL會保持它的打開狀態(tài)不變。我 此連接,另外還可以使用Connection屬性自行關(guān)閉它。 SqlConnectionnwindConn=newSqlConnection(connString); Northwindinterop_db=newNorthwind(nwindConn);varorders= fromoin whereo.Freight> selecto;//Freight>500.00M的訂單ADO.NETNorthwind500.00的所有Dontext包含在內(nèi)時,我們可以向Dontext提供此事務(wù)。通過.NETFramework創(chuàng)建事務(wù)的首選方法是使用TransactionScope對象。通過使用此方法,我們可以創(chuàng)建跨using(TransactionScopets=new{ 注意:不能將此方法用于所有數(shù)據(jù)庫。例如 連接在針對SQLServer2000服務(wù)器使用時無法提升系統(tǒng)務(wù)。它采取的方法是,只要它發(fā)現(xiàn)有使用事務(wù)范圍的情況,它就會務(wù)。它采取的方法是,只要它發(fā)現(xiàn)有使用事務(wù)范圍的情況,它就會 完整的分布式事務(wù)登記下面用一個例子說明一下事務(wù)的使用方法。在這里,也說

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論