1. 程式人生 > >一步一步學Linq to sql(五):儲存過程

一步一步學Linq to sql(五):儲存過程

導讀:
  
  普通儲存過程
  
  首先在查詢分析器執行下面的程式碼來建立一個儲存過程:
  createprocsp_singleresultset
  as
  setnocounton
  select*fromcustomers
  然後開啟IDE的伺服器資源管理器,之前我們從表中拖動表到dbml設計檢視,這次我們從儲存過程中找到剛才建立的儲存過程,然後拖動到設計檢視。在方法面板中可以看到已經建立了一個sp_singleresultset的方法,如下圖:
  
  5-1.jpg
  
  然後開啟Northwind.designer.cs,可以找到下面的程式碼:
  [Function(Name="dbo.sp_singleresultset")]
  publicISingleResultsp_singleresultset()
  {
  IExecuteResultresult = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
  return((ISingleResult)(result.ReturnValue));
  }
  我們可以發現,IDE為這個儲存過程單獨生成了返回結果集的實體定義,你可能會覺得很奇怪,IDE怎麼知道這個儲存過程將會返回哪些資料那?其實,在把儲存過程拖拽入dbml設計檢視的時候,IDE就執行了類似下面的命令:
  SET FMTONLY ON;
  exec Northwind.dbo.sp_singleresultset
  SET FMTONLY OFF;
  這樣就可以直接獲取儲存過程返回的元資料而無須執行儲存過程。
  其實我們儲存過程返回的就是顧客表的資料,如果你覺得為儲存過程單獨設定結果集實體有些浪費的話可以在儲存過程的屬性視窗中調整返回型別從“自動生成的型別”到Customer,不過以後你只能通過刪除方法面板中的儲存過程,然後重新新增來還原到“自動生成的型別”。下面,我們可以寫如下的Linq to object程式碼進行查詢:
  var單結果集儲存過程=
  fromc inctx.sp_singleresultset()
  wherec.CustomerID.StartsWith("A")
  selectc;
  在這裡確實是Linq to object的,因為查詢句法不會被整句翻譯成SQL,而是從儲存過程的返回物件中再去對物件進行查詢。SQL程式碼如下:
  EXEC @RETURN_VALUE = [dbo].[sp_singleresultset]
  -- @RETURN_VALUE: Output Int32 (Size = 0; Prec = 0; Scale = 0) []
  
  帶引數的儲存過程

  
  建立如下儲存過程:
  createproc[dbo].[sp_withparameter]
  @customerid nchar(5),
  @rowcount intoutput
  as
  setnocounton
  [email protected] =(selectcount(*)fromcustomers wherecustomerid [email protected])
  使用同樣的方法生成儲存過程方法,然後使用下面的程式碼進行測試:
  int? rowcount = -1;
  ctx.sp_withparameter("", refrowcount);
  Response.Write(rowcount);
  ctx.sp_withparameter("ALFKI", refrowcount);
  Response.Write(rowcount);
  結果輸出了“01”。說明ID為“”的顧客數為0,而ID為“ALFKI”的顧客數為1。儲存過程的輸出引數被封裝成了ref引數,對於C#語法來說非常合情合理。SQL程式碼如下:
  EXEC @RETURN_VALUE = [dbo].[sp_withparameter] @customerid = @p0, @rowcount = @p1 OUTPUT
  -- @p0: Input StringFixedLength (Size = 5; Prec = 0; Scale = 0) []
  -- @p1: InputOutput Int32 (Size = 0; Prec = 0; Scale = 0) [-1]
  -- @RETURN_VALUE: Output Int32 (Size = 0; Prec = 0; Scale = 0) []
  
  帶返回值的儲存過程

  
  再來建立第三個儲存過程:
  createproc[dbo].[sp_withreturnvalue]
  @customerid nchar(5)
  as
  setnocounton
  ifexists(select1 fromcustomers wherecustomerid [email protected])
  return101
  else
  return100
  生成方法後,可以通過下面的程式碼進行測試:
  Response.Write(ctx.sp_withreturnvalue(""));
  Response.Write(ctx.sp_withreturnvalue("ALFKI"));
  執行後程序輸出“100101”
  
  多結果集的儲存過程

  
  再來建立一個多結果集的儲存過程:
  createproc[dbo].[sp_multiresultset]
  as
  setnocounton
  select*fromcustomers
  select*fromemployees
  找到生成的儲存過程方法:
  [Function(Name="dbo.sp_multiresultset")]
  publicISingleResultsp_multiresultset()
  {
  IExecuteResultresult = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
  return((ISingleResult)(result.ReturnValue));
  }
  由於現在的VS2008會把多結果集儲存過程識別為單結果集儲存過程(只認識第一個結果集),我們只能對儲存過程方法多小動手術,修改為:
  [Function(Name="dbo.sp_multiresultset")]
  [ResultType(typeof(Customer))]
  [ResultType(typeof(Employee))]
  publicIMultipleResultssp_multiresultset()
  {
  IExecuteResultresult = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())));
  return(IMultipleResults)(result.ReturnValue);
  }
  然後使用下面的程式碼測試:
  var多結果集儲存過程= ctx.sp_multiresultset();
  varCustomers = 多結果集儲存過程.GetResult();
  varEmployees = 多結果集儲存過程.GetResult();
  GridView1.DataSource = fromemp inEmployees whereemp.FirstName.Contains("A") selectemp;
  GridView1.DataBind();
  GridView2.DataSource = fromc inCustomers wherec.CustomerID.StartsWith("A") selectc;
  GridView2.DataBind();
  
  使用儲存過程新增資料
  
  儲存過程除了可以直接呼叫之外,還可以用於實體的增刪改操作。還記得在《一步一步學Linq to sql(三):增刪改》中建立的留言簿程式嗎?下面我們就來改造這個程式,使用儲存過程而不是系統生成的SQL實現實體增刪改。首先,我們建立下面的儲存過程
  createprocsendmessage
  @username varchar(50),
  @message varchar(500)
  as
  insertintotbguestbook
  (id,username,posttime,[message],isreplied,reply)
  values
  (newid(),@username,getdate(),@message,0,')
  然後,開啟留言簿dbml,把儲存過程從伺服器資源管理器拖拽到設計檢視上。右鍵點選tbGuestBook實體類,選擇配置行為。如下圖,為插入操作選擇剛才建立的儲存過程方法,並進行引數匹配:
  
  5-2.jpg
  
  由於我們的儲存過程只接受2個引數,相應修改以下建立留言的按鈕處理事件:
  protectedvoidbtn_SendMessage_Click(objectsender, EventArgse)
  {
  tbGuestBookgb = newtbGuestBook();
  gb.UserName = tb_UserName.Text;
  gb.Message = tb_Message.Text;
  ctx.tbGuestBooks.Add(gb);
  ctx.SubmitChanges();
  SetBind();
  }
  執行程式後可以發現,在提交修改的時候呼叫了下面的SQL:
  EXEC @RETURN_VALUE = [dbo].[sendmessage] @username = @p0, @message = @p1
  -- @p0: Input AnsiString (Size = 5; Prec = 0; Scale = 0) [zhuye]
  -- @p1: Input AnsiString (Size = 11; Prec = 0; Scale = 0) [new message]
  -- @RETURN_VALUE: Output Int32 (Size = 0; Prec = 0; Scale = 0) []
  
  使用儲存過程刪除資料
  
  建立如下儲存過程:
  createprocdelmessage
  @id uniqueidentifier
  as
  deletetbguestbook [email protected]
  按照前面的步驟生成儲存過程方法,併為刪除操作執行這個儲存過程方法。在選擇引數的時候我們可以看到,ID分當前值和原始值,我們選擇當前值即可,如下圖:
  
  5-3.jpg
  
  無須改動任何邏輯程式碼,進行刪除留言操作後可以跟蹤到下面的SQL:
  EXEC @RETURN_VALUE = [dbo].[delmessage] @id = @p0
  -- @p0: Input Guid (Size = 0; Prec = 0; Scale = 0) [9e3c5ee3-2575-458e-899d-4b0bf73e0849]
  -- @RETURN_VALUE: Output Int32 (Size = 0; Prec = 0; Scale = 0) []
  
  使用儲存過程更改資料
  
  建立如下儲存過程:
  createprocreplymessage
  @id uniqueidentifier,
  @reply varchar(500)
  as
  updatetbguestbook [email protected],isreplied=1 [email protected]
  由於更新的時候並不會更新主鍵,所以我們可以為兩個引數都指定當前值。回覆留言後可以跟蹤到下面的SQL:
  EXEC @RETURN_VALUE = [dbo].[replymessage] @id = @p0, @reply = @p1
  -- @p0: Input Guid (Size = 0; Prec = 0; Scale = 0) [67a69d0f-a88b-4b22-8939-fed021eb1cb5]
  -- @p1: Input AnsiString (Size = 6; Prec = 0; Scale = 0) [464456]
  -- @RETURN_VALUE: Output Int32 (Size = 0; Prec = 0; Scale = 0) []
  假設有這樣一種應用,我們需要修改留言簿中不合法的使用者名稱:
  createprocmodiusername
  @oldusername varchar(50),
  @newusername varchar(50)
  as
  updatetbguestbook [email protected] whereusername [email protected]
  有個網友起名叫“admin”,我們要把所有這個名字修改為“notadmin”。那麼,可以如下圖設定update操作:
  
  5-4.jpg
  
  然後執行下面的測試程式碼:
  varmessages = fromgb inctx.tbGuestBooks
  selectgb;
  foreach(vargb inmessages)
  {
  if(gb.UserName == "admin")
  gb.UserName = "notadmin"
  }
  執行程式後能跟蹤到下面的SQL:
  SELECT [t0].[ID], [t0].[UserName], [t0].[PostTime], [t0].[Message], [t0].[IsReplied], [t0].[Reply]
  FROM [dbo].[tbGuestBook] AS [t0]
  
  EXEC @RETURN_VALUE = [dbo].[modiusername] @oldusername = @p0, @newusername = @p1
  -- @p0: Input AnsiString (Size = 5; Prec = 0; Scale = 0) [admin]
  -- @p1: Input AnsiString (Size = 8; Prec = 0; Scale = 0) [notadmin]
  -- @RETURN_VALUE: Output Int32 (Size = 0; Prec = 0; Scale = 0) []
  到這裡,你應該能明白當前值和原始值的含義了吧。
  

本文轉自
http://www.cnblogs.com/lovecherry/archive/2007/08/18/860935.html

相關推薦

Linq to sql儲存過程

導讀:      普通儲存過程      首先在查詢分析器執行下面的程式碼來建立一個儲存過程:   createprocsp_singleresultset   as   setnocounton   select*fromcustomers   然後開啟IDE的伺服器

跟廠長PHP7內核步步分析生命周期之模塊初始化階段

hle 持久 globals .post lean nco ror sign trie 上篇我們講到了模塊初始化階段,並得知它是由php_module_startup函數來實現的。該階段的主要作用是初始化變量、常量;註冊各種函數,比如工具、詞法、語法函數等;解析配置文件;

[神經網絡]使用Mobile-Net完成視覺識別

arc del img fault model coord graph 處理 mobile 1.環境配置 2.數據集獲取 3.訓練集獲取 4.訓練 5.調用測試訓練結果 6.代碼講解   本文是第五篇,講解如何調用測試訓練結果。 上一篇中我們輸出了訓練的模型,這一篇中我們通

從零開始 Web 之 Ajax同步異請求,數據格式

遊記 document 空閑 name center 20px 實現 resp 也會 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之

小白 Python 資料分析2Pandas 概述

人生苦短,我用 Python 前文傳送門: 小白學 Python 資料分析(1):資料分析基礎 概覽 首先還是幾個官方連結放一下: Pandas 官網:https://pandas.pydata.org/ Pandas 中文網:https://www.pypandas.cn/ Pandas Githu

小白 Python 資料分析12Pandas 資料透視表pivot_table

![](https://cdn.geekdigging.com/python/spider-blog/Python_logo.jpg) > 人生苦短,我用 Python 前文傳送門: [小白學 Python 資料分析(1):資料分析基礎](https://www.geekdigging.com/2020

小白 Python 資料分析16Matplotlib座標系

![](https://cdn.geekdigging.com/python/spider-blog/Python_logo.jpg) > 人生苦短,我用 Python 前文傳送門: [小白學 Python 資料分析(1):資料分析基礎](https://www.geekdigging.com/2020

LINQ開始之LINQ to Objects

opp 一對多 ear bool 元素 代碼 可用 etime 語法 LINQ概述   LINQ,語言集成查詢(Language Integrated Query),它允許使用C#或VB代碼以查詢數據庫相同的方式來操作不同的數據源。 LINQ體系結構 從上圖可以看出,LI

LINQ開始之LINQ to Objects

方法 current sel virtual start .com 代碼 命名空間 edt 前言 上一篇《從LINQ開始之LINQ to Objects(上)》主要介紹了LINQ的體系結構、基本語法以及LINQ to Objects中標準查詢操作符的使用方法。本篇則主要討

從AngularJS菜鳥到專家7Routing

們的 cat idt pan post 好的 書簽 廣播電臺 快速 這是"AngularJS – 七步從菜鳥到專家"系列的第七篇。在第一篇,我們展示了如何開始搭建一個AngularaJS應用。在第四、五篇我們討論了Angular內建的directives。上一篇了解了se

C#復習筆記4--C#3革新寫代碼的方式查詢表達式和LINQ to object

類型 否則 表達 數據集 clas 階段 邏輯 變量 RR 查詢表達式和LINQ to object(上) 本章內容: 流式處理數據和延遲執行序列 標準查詢操作符和查詢表達式轉換 範圍變量和透明標識符 投影、過濾和排序 聯接和分組 選擇要使用的語法 LINQ中的概

C#復習筆記4--C#3革新寫代碼的方式查詢表達式和LINQ to object

標識 all 麻煩 linq with write mar sel img 查詢表達式和LINQ to object(下) 接下來我們要研究的大部分都會涉及到透明標識符 let子句和透明標識符 let子句不過是引入了一個新的範圍變量。他的值是基於其他範圍變量的。let 標識

JPA映射關聯關系------映射單向多對的關聯關系

span AS 127.0.0.1 mysql5 單向 cti isa 嘗試 sequence 映射單向多對一的關聯關系 新建Customer.java: package com.dx.jpa.singlemanytoone; import java.ut

python手記requests寫爬蟲爬蟲簡介

上次將python的圖片處理庫簡單寫了下,也就基本處於玩的地步。哈哈,蠻嘲諷的,這次我嘗試著寫下爬蟲,有多深肯定是不敢保證的,畢竟能力有限。但是我會盡量去從原理上把爬蟲的東西說明白一些。讓大家有個直觀的認識,最後能自己寫出個簡單的定向小爬蟲,爬個小說,爬個圖片,爬首歌曲什麼的

java基礎for迴圈和維陣列

import java.util.Random; import java.util.Scanner; class DouDiZhu  {public static void main(String[] args) {//1. 生成54張牌 -- 不需要引數,返回值String[]String[] pic =

Mina、Netty、Twisted一起整合protobuf

ear ive obj con line 谷歌 encode etc 創建 protobuf是谷歌的Protocol Buffers的簡稱,用於結構化數據和字節碼之間互相轉換(序列化、反序列化),一般應用於網絡傳輸,可支持多種編程語言。protobuf怎樣使用這裏不再介紹

oracle sql 基礎數據定義語言創建和管理序列、索引、同義詞

aps span 最小值 into 全表掃描 條件 creat 返回 ext 許多應用程序要求使用唯一的數字作為主鍵的值,你即可以在應用程序中構建代碼來處理這種需求,也可以用一個序列來產生唯一的數字。如果你想要增進某些查詢的性能,你應該考慮創建一個索引,你也可

SQL基礎SQL函數

註釋 返回 訪問量 ces intro div group by -1 rownum 一、SQL Aggregate 函數:   SQL Aggregate 函數計算從列中取得的值,返回一個單一的值。 1、AVG() 函數   AVG() 函數返回數值列的平均值。   語法

SQL Server 2005中的分區表添加一個分區

eat 查詢 sch 另一個 rom 原創 查看 copyto art 所謂天下大事,分久必合,合久必分,對於分區表而言也一樣。前面我們介紹過如何刪除(合並)分區表中的一個分區,下面我們介紹一下如何為分區表添加一個分區。 為分區表添加一個分區,這種情況是時常會

MyBatis的動態SQL

pan 需要 9.png ack bat 鏈接 where In 標簽    用於實現動態SQL的元素主要有iftrimwheresetchoose(when、otherwise)foreach if標簽   Where標簽   Sql後面添加: where 1=1 ,那