ASP.NET框架中SQL Server 2008表值參數的操做

說明:html

本文將幫助你理解SQL Server 2008表值參數,這裏已經用了ASP.NET MVC Framework 3.0,但你能夠用ASP.NET MVC的其它框架。程序員

背景:ajax

在面向對象程序設計的開發環境中,不少狀況下,咱們須要存儲一整列對象到數據庫中,在這些狀況中,程序員採用如下兩個選項之一:數據庫

  • 用自定義分隔符來序列化對象陣列及其參數並在數據庫端將它們並行化,執行全部數據庫操做。但這使得計算變得至關複雜且費時,除了整列對象被當作varchar參數傳遞。
  • 使整列對象成環並經過單首創建鏈接在每一個陣列元素執行數據庫操做。它在編程上不那麼複雜但就咱們須要在每一個迭代上建立鏈接而言,依然不是一個可行的選項。

Microsoft SQL Server 2008能經過引入表值參數使得用戶能夠建立能輕易在存儲程序中使用的自定義類型table的參數,來解決上述兩個問題。編程

使用代碼:json

表值參數能夠用以下語法來建立:app

create type TVPType as table(
Name nvarchar(500),
Salary decimal(18,2),
Age int,
EndHeader bit
);

在上述代碼片斷中,咱們要注意建立自定義參數的類型和名稱。在本例中,是表參數結構跟隨表。一旦你執行代碼,就能夠在其中找到你的自定義參數。框架

ASP.NET,SQL Server

如今咱們須要建立程序來插入從應用中接收到的數據。咱們將使用以下存儲程序:函數

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

以下即爲應用的截圖(在用表值參數插入記錄到數據庫的先後)。

插入記錄前的頁面顯示:

ASP.NET,SQL

如今當咱們插入記錄時,我已容許用戶經過使用以下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」按鈕提交。

ASP.NET, SQL

咱們能夠經過生成一個請求,用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」消息時,它將再也不可見。而主頁將顯示以下:

ASP.NET, SQL

須要注意的點:

  • 實體框架目前不支持表值參數。
  • 表值參數不能被編輯但能夠被刪除和重建,僅當你的數據庫中任意存儲程序沒有引用該表值參數時。
  • 表值參數在只讀模式中使用。
  • 表值參數不能被用於數據庫中用戶定義函數。
  • DataTable的表值參數和結構應該匹配。好比,列應該被定義在同一個位置。

點擊下載源代碼

相關文章
相關標籤/搜索