說明:html
本文將幫助你理解SQL Server 2008表值參數,這裏已經用了ASP.NET MVC Framework 3.0,但你能夠用ASP.NET MVC的其它框架。程序員
背景:ajax
在面向對象程序設計的開發環境中,不少狀況下,咱們須要存儲一整列對象到數據庫中,在這些狀況中,程序員採用如下兩個選項之一:數據庫
Microsoft SQL Server 2008能經過引入表值參數使得用戶能夠建立能輕易在存儲程序中使用的自定義類型table的參數,來解決上述兩個問題。編程
使用代碼:json
表值參數能夠用以下語法來建立:app
create type TVPType as table( Name nvarchar(500), Salary decimal(18,2), Age int, EndHeader bit );
在上述代碼片斷中,咱們要注意建立自定義參數的類型和名稱。在本例中,是表參數結構跟隨表。一旦你執行代碼,就能夠在其中找到你的自定義參數。框架
如今咱們須要建立程序來插入從應用中接收到的數據。咱們將使用以下存儲程序:函數
create proc AddDetails @tvp TVPType readonly as begin insert into TVPTable(Name, Age, Salary) select t.Name,t.Age,t.Salary from @tvp t; end
由此如今咱們已經完成了數據庫方面,將轉向應用方面。打開一個新的MVC項目或一個你想要使用的項目。我已經使用了類型化數據集替代實體框架,由於實體框架不支持可以用於表值參數的結構化類型參數。url
以下即爲應用的截圖(在用表值參數插入記錄到數據庫的先後)。
插入記錄前的頁面顯示:
如今當咱們插入記錄時,我已容許用戶經過使用以下JavaScript代碼插入任意量的記錄:
function addRow() { var table = document.getElementById('recordTable').lastChild; if (table) { var id = Number(table.children[table.children.length-1].id); if (!isNaN(id)) { id+=1; var child = document.createElement('tr'); child.id = id; var html = '<input type="text" id="name_' + id + '" maxlength="50"/>'; html += '<input type="text" id="age_' + id + '"/>'; html += '<input type="text" id="salary_' + id + '"/>'; child.innerHTML = html; table.appendChild(child); } } }
用戶能夠用「Add more」按鈕添加新行,最後用「Submit」按鈕提交。
咱們能夠經過生成一個請求,用JSON對象傳送全部數據到控制器。以下便是完成上述任務的JavaScript代碼:
function submitRecords() { var table = document.getElementById('recordTable').lastChild; if (table) { var childArr = table.children; if (childArr.length > 0) { var jsonArr={tvp:[]}; var nameObj, ageObj, salaryObj, id; var counter = 0; for (var i = 1; i < childArr.length; i++) { id = childArr[i].id; nameObj = document.getElementById('name_' + id); ageObj = document.getElementById('age_' + id); salaryObj = document.getElementById('salary_' + id); if (nameObj != null && nameObj.value.trim() != '' && ageObj != null && ageObj.value.trim() != '' && salaryObj != null && salaryObj.value.trim() != '') { jsonArr.tvp.push({ "name":nameObj.value.trim(), "age":ageObj.value.trim(), "salary":salaryObj.value.trim() }); } } if (jsonArr.tvp.length > 0) { $.ajax({ url: "../TVP/SubmitRecord", data:{"data":JSON.stringify(jsonArr)}, type: "POST" }); } else alert("Add data please"); } } }
在控制器一方,咱們已經建立了一個函數SubmitRecord來接收咱們的AJAX請求並將數據從AJAX請求中傳遞到相應的模型中。
[HttpPost] public ActionResult SubmitRecord(string data) { TVPModel.StoreValues(data); return View(); }
在上述代碼中,HttpPost屬性指定了調用函數(接收當PSOT請求時)。咱們已經用NewtonSoftJson庫來在模型類別上(解析JSON數據並將其存儲到DataTable)解析JSON對象。
public static void StoreValues(string data) { JToken token = JObject.Parse(data); var tvp=token.SelectToken("tvp"); DataTable recordTable = Params.GetDetailsTable(); foreach (var value in tvp) { DataRow row = recordTable.NewRow(); row["Name"] = value.SelectToken("name"); row["Age"] = value.SelectToken("age"); row["Salary"] = value.SelectToken("salary"); ; row["EndHeader"] = true; recordTable.Rows.Add(row); } TVPBL bl = new TVPBL(); bl.InsertTVP(recordTable); }
建立的DataTable被做爲參數傳送到數據庫程序。該DataTable應該和數據庫端的所述類型有着一樣的結構。咱們已經建立了一個BL類,負責爲咱們的類型化數據集建立一個表適配器並調用指定的程序。
public void InsertTVP(DataTable tvpTable) { TVPTableTableAdapter adapter = GetTvpTableAdapter(); adapter.AddDetails(tvpTable); }
在完成上述程序後,咱們的數據被存儲在數據庫中。如今當瀏覽主頁顯示「No details to show」消息時,它將再也不可見。而主頁將顯示以下:
須要注意的點:
點擊下載源代碼