2010-07-13 20 views
7

Trong codebehind bạn sẽ thêm TVP làm SqlDbType.Structured cho một thủ tục được lưu trữ Nhưng điều này không tồn tại trong điều khiển ASP.NET SqlDataSource.Cách thiết lập ASP.NET SQL Datasource để chấp nhận TVP

tôi đã được lưu trữ Datatables của tôi trong các biến session (đừng lo lắng họ còn nhỏ!) Và tôi cần phải vượt qua những người như các thông số cho SqlDataSource (trong đó có một số đối tượng databound)

Tôi chỉ Datasource với biến phiên nhưng không thành công khi chuyển đổi thành loại bảng.

EDIT: Hãy nói rằng tôi lấy biến Session ra khỏi phương trình (bởi vì, thực sự, nó hoàn toàn tiếp tuyến)

Phải có cách nào tôi có thể đính kèm một DBType.Structured đến một SqlDataSource. Danh sách xem của tôi phù hợp với dữ liệu nhưng các thủ tục lưu trữ mà chúng được đính kèm phải lấy

của TVP Tôi không thể tin rằng sẽ không có cách nào để gửi thông số tham chiếu TVP cho SQLDataSource? Lựa chọn thay thế của tôi là gì?

EDIT2: Tôi đã nhìn vào việc tạo ra một số tùy chỉnh cho các SqlDataSource nhưng nó vẫn có vẻ với tôi như phương pháp "eval" nó sẽ không được hài lòng với kiểu dữ liệu có cấu trúc

EDIT3: Đó là bắt đầu xuất hiện rằng tùy chọn duy nhất của tôi là làm tất cả công việc trong codebehind cho các điều khiển dữ liệu của tôi. Tôi đã thêm tiền thưởng trong trường hợp bất kỳ ai khác có một giải pháp thanh lịch.

EDIT4: Có, có lẽ, cách mà tôi có thể chuyển bảng làm đối tượng cho một thủ tục được lưu trữ, sau đó có SQL Server chuyển đổi nó sang TVP?

+1

Có một số lý do khiến rất ít người vẫn sử dụng các điều khiển đó và tại sao mọi người không lưu trữ bảng dữ liệu trong phiên. Đó có thể là thời gian để chuyển sang bước tiếp theo trong giáo dục phát triển của bạn. – NotMe

+2

Tôi hiểu lý do chống lại lưu trữ dữ liệu trong phiên; đây là một môi trường được kiểm soát mà việc sử dụng của tôi là thích hợp. Đối với khiếu nại của bạn rằng "rất ít người vẫn sử dụng các điều khiển đó" Tôi chưa bao giờ nghe điều đó. Bạn có đề xuất có vấn đề cố hữu với việc sử dụng điều khiển SqlDataSource không? Xem xét nó hoạt động khá tốt trong hầu hết các tình huống mà nó được thiết kế tôi không thấy điểm của bạn chống lại nó. Mặt khác, tôi mở các đề xuất của bạn về cách liên kết tốt nhất nhiều điều khiển với dữ liệu một cách tao nhã như SqlDataSource – Matthew

+1

SqlDataSource đặt trước các tham số có giá trị của một số lượng đáng kể các năm, tôi sẽ không ngạc nhiên khi khả năng không tồn tại và chưa được thêm vào. – womp

Trả lời

4

Tôi biết bạn đã chỉnh sửa để nói phiên là không quan trọng, tuy nhiên tôi có thể làm việc này bằng cách sử dụng SessionParameter. Tôi có cảm giác nó cũng sẽ làm việc với một ControlParameter.

Vì vậy, bạn có một loại bảng người dùng định nghĩa:

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

và một thủ tục lưu trữ sử dụng nó:

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

sau đó một GridView ràng buộc với một SqlDataSource mà chọn từ sproc của bạn, đi qua 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> 

và cuối cùng là một chút gì đó để đặt DataTable i nĐể phiên giao dịch, mặc dù bạn nói rằng bạn đã có nó ở đó 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> 

mà kết quả trong một GridView mịn ràng buộc:

alt text

và truy vấn được tạo sau đây từ 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 @[email protected] 

Đây là .NET 4, MSSQL Express 2010, nhưng cũng hoạt động thấp hơn.

+0

Công trình này! Vì vậy, có vẻ như vấn đề là nguồn dữ liệu theo mặc định muốn một kiểu dữ liệu cho các tham số. Nếu nó bị xóa và cố tình làm mờ thì các hàm sds hoạt động đúng cách. Cảm ơn bạn Tôi đã kích hoạt lại tiền thưởng và đánh dấu bạn là câu trả lời – Matthew

+0

Lưu ý quan trọng: * chỉ * có vẻ như hoạt động với tùy chọn trường phiên và không có loại được chỉ định. Hơn nữa, các trường phiên cần phải được đặt thành giá trị dữ liệu chính xác về kích thước tải biểu mẫu. Để giải thích điều này (trong trường hợp các trường phiên không thích hợp), tôi tạm thời đặt trường phiên, rebind các điều khiển, sau đó xóa trường phiên – Matthew

0

Tạo lớp trung gian hoặc bộ điều hợp sẽ đóng vai trò như một nguồn cho bất kỳ dữ liệu tự động nào mà bạn đã có. Sau đó, bạn có toàn quyền kiểm soát để chuẩn bị args cho sproc chính xác theo cách nó cần chúng.

+0

Điều này tránh được việc sử dụng SDS với TVP, phải không? Tôi đã biết tôi có thể viết các lớp học để nguồn đối tượng dữ liệu của tôi ... vấn đề là cho ăn các datatables vào đối tượng nguồn dữ liệu hiện có. – Matthew

+0

Khi phải đối mặt với các lớp cồng kềnh, nghệ thuật trốn tránh là một đức tính tuyệt vời :-) Về mặt kỹ thuật, bạn có thể lấy được từ SqlDataSourceView và ghi đè lên ExecuteSelect vv để nó vẫn trông và quacks giống như SqlDataSourceView. Bạn có thể đọc thực hiện hiện tại trong Reflector và tìm một nơi để làm mod. – ZXX

Các vấn đề liên quan