如何设置 ASP.NET SQL 数据源以接受 TVP

发布于 2024-09-09 04:07:25 字数 594 浏览 0 评论 0原文

在代码隐藏中,您可以将 TVP 添加为存储过程的 SqlDbType.Structured 但这在 ASP.NET SqlDataSource 控件中不存在。

我已将数据表存储在会话变量中(不用担心它们很小!),我需要将它们作为参数传递给 SqlDataSource(它有许多数据绑定对象)

我将数据源指向会话变量,但它失败到表类型的转换。

编辑: 假设我将 Session 变量从等式中取出(因为,实际上,它完全是切线的),

必须有一种方法可以将 DBType.Structured 附加到 SQLDataSource。 我的列表视图适当地进行了数据绑定,但它们所附加的存储过程必须采用 TVP

我无法相信没有办法为 SQLDataSource 发送 TVP 参数? 我有什么选择?

编辑2: 不满意

我一直在考虑为 SqlDataSource 创建自定义参数,但在我看来,它的“eval”方法对结构化数据类型EDIT3 : 看来我唯一的选择是在代码隐藏中为我的数据绑定控件完成所有工作。我添加了赏金,以防其他人有一个优雅的解决方案。

编辑4: 也许有一种方法可以将表作为对象传递给存储过程,然后让 SQL Server 将其转换为 TVP?

In the codebehind you would add the TVP as a SqlDbType.Structured for a stored procedure
But this doesn't exist in an ASP.NET SqlDataSource control.

I have stored my Datatables in session variables (don't worry they are small!) and I need to pass those as parameters to the SqlDataSource (which has a number of databound objects)

I pointed the Datasource to the session variable but it fails on the conversion to the table type.

EDIT:
Let's say I take the Session variable out of the equation (because, really, it's completely tangential)

There must be a way I can attach a DBType.Structured to a SQLDataSource.
My Listviews are appropriately databound but the store procedures to which they are attached must take TVP's

I cannot believe that there would be no way to send a TVP paramater for a SQLDataSource?
What are my alternatives?

EDIT2:
I've been looking into creating a custom parameter for the SqlDataSource but it still seems to me like its "eval" method won't be happy with the structured data type

EDIT3:
It's beginning to appear that my only option is to do all the work in codebehind for my databound controls. I added a bounty in case anybody else has an elegant solution.

EDIT4:
Is there, perhaps, a way that I can pass the table as an object to a stored procedure, then have SQL Server convert it to the TVP?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄暮涼年 2024-09-16 04:07:25

我知道您已经编辑说会话并不重要,但是我能够使用 SessionParameter 来完成此操作。我有一种感觉,它也可以与 ControlParameter 一起使用。

因此,您有一个用户定义的表类型:

CREATE TYPE TVPType AS TABLE(
    Col1 int,
    Col2 int)
GO

以及一个使用它的存储过程:

CREATE PROC TVPProc(@TVP AS TVPType READONLY) AS
    SELECT * FROM @TVP

然后是一个绑定到从存储过程中选择的 SqlDataSource 的 GridView,传递一个 SessionParameter:

<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" />
<asp:SqlDataSource ID="SqlDataSource1" SelectCommand="TVPProc" runat="server" SelectCommandType="StoredProcedure" ConnectionString="Server=(local)\sqlexpress;Database=Graph;Integrated Security=True">
    <SelectParameters>
        <asp:SessionParameter SessionField="MyDataTable" Name="TVP" />
    </SelectParameters>
</asp:SqlDataSource>

最后是一些将 DataTable 放入会话中的东西,尽管您假设你已经在那里了:

(VB)

<script runat="server">
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim MyDataTable As New System.Data.DataTable

        MyDataTable.Columns.AddRange({
            New System.Data.DataColumn("Col1", GetType(integer)),
            New System.Data.DataColumn("Col2", GetType(integer))})

        MyDataTable.Rows.Add(22, 33)
        MyDataTable.Rows.Add(44, 55)
        MyDataTable.Rows.Add(66, 77)

        Session("MyDataTable") = MyDataTable
    End Sub
</script>

(C#)

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        System.Data.DataTable MyDataTable = new System.Data.DataTable();
        MyDataTable.Columns.AddRange(
            new System.Data.DataColumn[] {
                new System.Data.DataColumn("Col1", typeof (int)),
                new System.Data.DataColumn("Col2", typeof (int))});

        MyDataTable.Rows.Add(22, 33);
        MyDataTable.Rows.Add(44, 55);
        MyDataTable.Rows.Add(66, 77);

        Session["MyDataTable"] = MyDataTable;
    }
</script>

这会产生一个精细绑定的 GridView:

alt text

和以下是从 Profiler 生成的查询:

declare @p1 dbo.TVPType
insert into @p1 values(22,33)
insert into @p1 values(44,55)
insert into @p1 values(66,77)

exec TVPProc @TVP=@p1

这是 .NET 4、MSSQL Express 2010,但也应该在较低版本下工作。

I know you've edited to say session is of no importance, however I was able to get this working using a SessionParameter. I have a feeling it would also work with a ControlParameter.

So you have a user-defined table type:

CREATE TYPE TVPType AS TABLE(
    Col1 int,
    Col2 int)
GO

and a stored procedure that uses it:

CREATE PROC TVPProc(@TVP AS TVPType READONLY) AS
    SELECT * FROM @TVP

then a GridView bound to a SqlDataSource that selects from your sproc, passing a SessionParameter:

<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" />
<asp:SqlDataSource ID="SqlDataSource1" SelectCommand="TVPProc" runat="server" SelectCommandType="StoredProcedure" ConnectionString="Server=(local)\sqlexpress;Database=Graph;Integrated Security=True">
    <SelectParameters>
        <asp:SessionParameter SessionField="MyDataTable" Name="TVP" />
    </SelectParameters>
</asp:SqlDataSource>

and finally a little something to put a DataTable into the session, although you say you already have it there anyway:

(VB)

<script runat="server">
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim MyDataTable As New System.Data.DataTable

        MyDataTable.Columns.AddRange({
            New System.Data.DataColumn("Col1", GetType(integer)),
            New System.Data.DataColumn("Col2", GetType(integer))})

        MyDataTable.Rows.Add(22, 33)
        MyDataTable.Rows.Add(44, 55)
        MyDataTable.Rows.Add(66, 77)

        Session("MyDataTable") = MyDataTable
    End Sub
</script>

(C#)

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        System.Data.DataTable MyDataTable = new System.Data.DataTable();
        MyDataTable.Columns.AddRange(
            new System.Data.DataColumn[] {
                new System.Data.DataColumn("Col1", typeof (int)),
                new System.Data.DataColumn("Col2", typeof (int))});

        MyDataTable.Rows.Add(22, 33);
        MyDataTable.Rows.Add(44, 55);
        MyDataTable.Rows.Add(66, 77);

        Session["MyDataTable"] = MyDataTable;
    }
</script>

which results in a finely bound GridView:

alt text

and the following generated query from Profiler:

declare @p1 dbo.TVPType
insert into @p1 values(22,33)
insert into @p1 values(44,55)
insert into @p1 values(66,77)

exec TVPProc @TVP=@p1

This is .NET 4, MSSQL Express 2010, but should work lower as well.

七月上 2024-09-16 04:07:25

创建中间类或适配器,将其用作您已有的任何自动数据绑定的源。然后,您就可以完全控制按照存储过程需要的方式为存储过程准备参数。

Make intermediary class or adapter that will serve as a source to whatever automatic data bounding you already have. Then you are in full control to prepare args for the sproc exactly the way it needs them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文