<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      happyhippy

      這個世界的問題在于聰明人充滿疑惑,而傻子們堅信不疑。--羅素
      0. 說明

          Linq to Sql,以下簡稱L2S。
          以下文中所指的兩層和三層結構,分別如下圖所示:

      Linq2SqlN層 

          準確的說,這里的分層并不是特別明確:
      (1) 生成的DataContext(Linq t0 SQL Runtime)和Entity是放在一個文件中的,物理上不能切割開來;上圖只是展示邏輯上的結構。
      (2) 拿上圖右邊的三層結構來說,鑒于第(1)點,UI層就可以跨越BusinessLogic層,直接訪問L2S層,這可能不是我們期望的。對于這個問題,可以有如下兩種辦法:A.建立自己的Entity層(DomainModel,UI與BL之間使用DomainModel,BL將DomainModel轉換成L2S的Entity后,再交給L2S Runtime進行數據庫更新);  B.告訴UI層開發人員不要訪問L2S Runtime-,-

       

      1. 生成DataContext和Entity
         1.1 使用VS自帶的L2S對象關系設計器(O/R設計器)

          如果程序很簡單只是拿來玩兒的,就少數幾個表,可以直接使用此法,將表/視圖/存儲過程從數據源中拖拽到設計器中即可。但如果系統中的表很多,拖著拖著就把自己給拖暈了……

         1.2 使用SqlMeta工具

          用法見MSDN。    

      sqlmetal /conn:"Data Source=server;Initial Catalog=database;Persist Security Info=True;User ID=sa;Password=password" /namespace:DataEntity /code:_Entity.cs /language:csharp /context:EntityDataContext /serialization:Unidirectional /views
         1.3 手工建立實體定義或者XML映射

          太多活要干,如果沒有特殊場景必須手工Code這堆東西的話,建議還是省省……
      具體可以參考MSDN:
      使用代碼編輯器自定義實體類 (LINQ to SQL)

       

      2. 兩層應用下的CUD操作

          兩層應用下的較為簡單,MSDN中有例子,借花獻佛:

      2.1 新增
         1: Order ord = new Order
         2: {
         3:     OrderID = 12000,
         4:     ShipCity = "Seattle",
         5:     OrderDate = DateTime.Now
         6:     // …
         7: };
         8: db.Orders.InsertOnSubmit(ord);
         9: db.SubmitChanges();
      2.2 更新
         1: //1.查詢需要修改的紀錄[Lazy Load]
         2: IQueryable<Order> query =
         3:     from ord in db.Orders
         4:     where ord.OrderID == 11000
         5:     select ord;
         6: //2.修改
         7: foreach (Order ord in query)
         8: {
         9:     ord.ShipName = "Mariner";
        10:     ord.ShipVia = 2;
        11:     // Insert any additional changes to column values.
        12: }
        13: //3.保存
        14: db.SubmitChanges();
      2.3 刪除
         1: //1.查詢需要修改的紀錄[Lazy Load]
         2: IQueryable<Order> query =
         3:     from ord in db.Orders
         4:     where ord.OrderID == 11000
         5:     select ord;
         6: //2.修改
         7: foreach (Order ord in query)
         8: {
         9:     db.Orders.DeleteOnSubmit(ord);
        10: }
        11: //3.提交更改
        12: db.SubmitChanges();

       

       

      3. 多層應用下的CUD操作

          新增操作同上。
          但修改和刪除操作則需要做調整。在文章起始位置的分層結構圖中可以看到,層之間是以Entity作為數據傳輸對象。由于Entity的狀態是有DataContext進行監控的,脫離了DataContext,則L2S無法知道對象是否做了更新、做了什么更新。譬如我的BusinessLogic被封裝在一個WCF應用中,在將Entity通過網絡序列化到客戶端時,這些Entity會與其DataContext分離;當Entity再從客戶端傳回到服務器端時,服務器端使用的是一個新的DataContext,繼續用上面的方法來操作的話,執行時會報錯。

         關于對象狀態及跟蹤,可以參考MSDN:對象狀態與更改跟蹤 (LINQ to SQL)

          一種解決辦法是:將上層傳過來的Entity重新Attach到新的DataContext中。

      3.1 新增

      新增不用Attach,直接按照2.1中同樣的操作方式即可。(同2.1)

      3.2 刪除
         1: public void DeleteOrder(Order order)
         2: {
         3:     NorthwindClasses1DataContext db = new NorthwindClasses1DataContext(connectionString);
         4:  
         5:     db.Orders.Attach(order, false); //重新Attach一次
         6:     db.Orders.DeleteOnSubmit(order);
         7:     try
         8:     {
         9:         db.SubmitChanges(ConflictMode.ContinueOnConflict);
        10:     }
        11:     catch (ChangeConflictException e)
        12:     {
        13:        //處理更改沖突
        14:     }
        15: }
      3.3 修改

          Attach可以解決刪除問題,但并不能解決所有的更新問題。因為在L2S中,需要支持開放式并發檢查。L2S支持以下三種開放式并發方案中的更新:(有關開放式并發的更多信息,請參見MSDN:開放式并發概述 (LINQ to SQL)
      (1).基于時間戳或 RowVersion 號的開放式并發。
      (2).基于實體屬性子集的原始值的開放式并發。
      (3).基于完整原始實體和已修改實體的開放式并發。

          通俗的講,就是如下根據如下三中處理并發的方式:
      (1). 數據庫表結構定義中包含時間戳(timestamp)字段:

          由于時間戳的值惟一,每次更新記錄時其值會同時進行更新,因此只用根據主鍵+時間戳,就能判斷記錄是否被其他人更新過;如果沒有被更新過,則可以進行更新;如果被更新過,則引發ChangeConflictException異常。

          時間戳字段對應的Entity定義中屬性的Attribute會長成這個樣子:[Column(Storage="_TimestampFieldName", AutoSync=AutoSync.Always, DbType="rowversion NOT NULL", CanBeNull=false, IsDbGenerated=true, IsVersion=true, UpdateCheck=UpdateCheck.Never)]。

         此時可以按照3.1類似的方式來Attach修改后的Entity,并提交更改到數據庫:(可以用Sql Server的Profile來查看生成的TSQL)

         1: public void UpdateOrder(Order order)
         2: {
         3:     NorthwindClasses1DataContext db = new NorthwindClasses1DataContext(connectionString);
         4:  
         5:     db.Orders.Attach(order, true);
         6:     try
         7:     {
         8:         db.SubmitChanges();
         9:     }
        10:     catch (ChangeConflictException e)
        11:     {
        12:        //處理更改沖突
        13:     }
        14: }


      (2). 如果數據庫表結構定義中不包含時間戳(timestamp)字段:

          如果繼續用上面(1)的方式來更新,編譯時不會報錯,但執行時會報錯。
          此時L2S不知道該咋更新了,于是就需要人為地告訴L2S該更新啥,具體包含如下兩種方式
          (a). 提供原始對象及更新后的屬性值

         1: public void UpdateOrder(Order o, short? newValue1, short? newValue2)
         2: {
         3:     using (NorthwindClasses1DataContext db = new NorthwindClasses1DataContext(connectionString))
         4:     {
         5:         db.Orders.Attach(o, false);//o必須是原始的沒有更改過的實體對象
         6:  
         7:         o.XXOO = newValue1;
         8:         o.OOXX = newValue2;
         9:         try
        10:         {
        11:              db.SubmitChanges();
        12:         }
        13:         catch (ChangeConflictException e)
        14:         {
        15:             // 處理更改沖突
        16:         }
        17:     }
        18: }

          (b). 提供原始對象及更新后的對象

         1: public void UpdateOrder(Order originalOrder, Order newOrder)
         2: {
         3:     using (NorthwindClasses1DataContext db = new NorthwindClasses1DataContext(connectionString))
         4:     {
         5:         db.Orders.Attach(newOrder, originalOrder);//originalOrder必須是原始的沒有更改過的實體對象
         6:  
         7:         try
         8:         {
         9:              db.SubmitChanges();
        10:         }
        11:         catch (ChangeConflictException e)
        12:         {
        13:             // 處理更改沖突
        14:         }
        15:     }
        16: }

          第一種方式只需要對表增加TimeStamp類型的字段;而后面兩種更新方式都需要一些額外的代碼來進行處理;相比之下,還是第一種方式相對省力點兒。

       

          如果表比較多,逐個表增加TimeStamp字段就比較討人厭了,于是有了下面的SQL,來為所有的表增加時間戳列:

         1: DECLARE @Table Table(ID int identity(1,1), TableName nvarchar(100));
         2: DECLARE @Index int, @TotalCount int;
         3: DECLARE @TableName nvarchar(100);
         4:  
         5: INSERT INTO @Table(TableName)
         6:     SELECT TOP 100 PERCENT T.name FROM dbo.sysobjects T WHERE (T.xtype = 'u');
         7: SET @TotalCount = @@RowCount;
         8:  
         9: SET @Index = 1;
        10: WHILE(@Index <= @TotalCount)
        11: BEGIN
        12:     SELECT @TableName = TableName FROM @Table WHERE ID=@Index;
        13:     
        14:     IF(NOT Exists(SELECT 1 FROM syscolumns WHERE id = object_id(@TableName) AND number = 0 
        15:                 AND type_name(xusertype) = 'timestamp'))
        16:     BEGIN
        17:         EXEC('ALTER TABLE ' + @TableName + ' ADD [Timestamp] timestamp')
        18:     END
        19:     
        20:     SET @Index = @Index + 1;
        21: END

      尤其需要注意的是:

      在嘗試進行更新之前,不要將從數據庫中檢索數據作為一種獲取原始值的方式。

       

      4. 批量更新、批量刪除

          然而,上面的處理方式只是處理的最基本的CUD操作,而實際應用中的業務邏輯不會這么簡單。如果涉及到稍為復雜點兒的應用,譬如我要根據一個外部傳進來的條件,執行批量修改、批量刪除,該咋處理呢?

          關于批量刪除和批量更新,老趙曾提出過自己的方案:擴展LINQ to SQL:使用Lambda Expression批量刪除數據,其思路就是實現一個Expression<Func<T, bool>>解析器,并將Expression解析為最終需要執行的TSQL。在老趙的同篇英文博客中,有人在回復中提出了另一個思路,對L2S生成的TSQL進行包裝,將其作為Update/Delete語句中的子查詢,這樣就可以直接復用L2S的查詢解析器,使用L2S解析器提供的全部功能了;接下來有人將這個思路進行了實現:Batch Updates and Deletes with LINQ to SQL。原文作者寫的非常詳細了,并提供了源代碼,可以下載回來學習或者直接復用。

         1: string productName = new StringBuilder("test").Append("productName").ToString();
         2: int productID = new Random().Next(10000000, Int32.MaxValue);
         3: Expression<Func<Products, bool>> predicate = p => p.ProductName.Contains(productName);
         4: Expression<Func<Products, Products>> evaluator = 
         5:     p => new Products() { UnitPrice = p.UnitPrice + 1, ProductName = "Test" };
         6:  
         7: UpdateBatch(predicate, evaluator);  //批量更新
         8: DeleteBatch(predicate);  //批量刪除
         9: MultiSelect();           //批量查詢
        10: DeleteByPK(productID);   //按主鍵刪除
        11:  
        12: public void UpdateBatch(Expression<Func<Products, bool>> predicate,
        13:     Expression<Func<Products, Products>> evaluator)
        14: {
        15:     using (NorthWindDataContext context = new NorthWindDataContext())
        16:     {
        17:         context.Products.UpdateBatch(predicate, evaluator);
        18:     }
        19: }
        20:  
        21: public void DeleteBatch(Expression<Func<Products, bool>> predicate)
        22: {
        23:     using (NorthWindDataContext context = new NorthWindDataContext())
        24:     {
        25:         context.Products.DeleteBatch(predicate);
        26:     }
        27: }
        28:  
        29: public void MultiSelect()
        30: {
        31:     using (NorthWindDataContext context = new NorthWindDataContext())
        32:     {
        33:         var query1 = (from P in context.Products select P).Take(2);
        34:         var query2 = (from S in context.Suppliers select S).Take(2);
        35:         IMultipleResults result = context.SelectMutlipleResults(query1, query2);
        36:  
        37:         List<Products> products = result.GetResult<Products>().ToList();
        38:         List<Suppliers> suppliers = result.GetResult<Suppliers>().ToList();
        39:         ObjectDumper.Write(products);
        40:         ObjectDumper.Write(suppliers);
        41:     }
        42: }
        43:  
        44: public void DeleteByPK(int productID)
        45: {
        46:     using (NorthWindDataContext context = new NorthWindDataContext())
        47:     {
        48:         context.Products.DeleteByPK(productID);
        49:     }
        50: }

          具體生成的SQL,可以用SQL  Server Profile來查看。


       

      參考《MSDN》:
      1.做出和提交數據更改 (LINQ to SQL)
      2.N 層應用程序中的數據檢索和 CUD 操作 (LINQ to SQL)
      3.開放式并發概述 (LINQ to SQL)
      4.對象狀態與更改跟蹤 (LINQ to SQL)

      posted on 2010-01-29 16:07  Silent Void  閱讀(4241)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 国产成人一区二区三区免费| 日韩成人高精品一区二区| 四平市| 亚洲性日韩一区二区三区| 99久久久国产精品免费无卡顿| 国产精品自拍午夜福利| 欧美性猛交xxxx乱大交极品| 中文字幕在线不卡一区二区| 国产揄拍国产精品| 国产亚洲精品久久久久5区| 自拍偷自拍亚洲精品播放| 少妇xxxxx性开放| 公喝错春药让我高潮| 一区二区三区在线 | 欧洲| 被黑人伦流澡到高潮HNP动漫| 国产精品偷伦费观看一次| 国产果冻豆传媒麻婆| √新版天堂资源在线资源| 国产高颜值极品嫩模视频| 日本一区二区三区免费播放视频站| 人人澡人摸人人添| 综合成人亚洲网友偷自拍| 老司机亚洲精品一区二区| 九九热爱视频精品视频| 高密市| 中文字幕无线码免费人妻| JIZZJIZZ国产| 看全黄大色黄大片视频| 四虎成人在线观看免费| 少妇激情一区二区三区视频小说 | 男女扒开双腿猛进入爽爽免费看| 日韩一区二区三区女优丝袜| 日韩精品毛片无码一区到三区| 男女性高爱潮免费网站| 欧美www在线观看| 日韩人妻无码一区二区三区99 | 无码AV中文字幕久久专区| A级日本乱理伦片免费入口| 人妻丝袜无码专区视频网站| 天天综合色一区二区三区| 欧美一区内射最近更新|