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的表值参数和结构应该匹配。好比,列应该被定义在同一个位置。

点击下载源代码

相关文章
相关标签/搜索