Nếu bạn đang sử dụng SQL 2008, bạn có thể tạo một stored procedure mà chấp nhận một bảng Parameter Quý (TVP) và sử dụng để thực hiện ADO.net các thủ tục lưu trữ và vượt qua một DataTable với nó:
Trước tiên, bạn cần tạo gõ vào SQL server:
CREATE TYPE [dbo].[udt_UserId] AS TABLE(
[UserId] [int] NULL
)
Sau đó, bạn cần phải viết một thủ tục lưu trữ mà chấp nhận loại hình này như một tham số:
CREATE PROCEDURE [dbo].[usp_DoSomethingWithTableTypedParameter]
(
@UserIdList udt_UserId READONLY
)
AS
BEGIN
SELECT userId, username
FROM Users
WHERE userId IN (SELECT UserId FROM @UserIDList)
END
Bây giờ từ .net, bạn không thể sử dụng LINQ vì nó không hỗ trợ Thông số giá trị bảng; vì vậy bạn phải viết một hàm có ADO cũ đơn giản.net, lấy một DataTable và chuyển nó đến thủ tục đã lưu trữ: Tôi đã viết một hàm generic mà tôi sử dụng có thể thực hiện điều này cho bất kỳ thủ tục được lưu trữ nào miễn là nó chỉ lấy tham số được gõ một bảng, bất kể nó là gì;
public static int ExecStoredProcWithTVP(DbConnection connection, string storedProcedureName, string tableName, string tableTypeName, DataTable dt)
{
using (SqlConnection conn = new SqlConnection(connection.ConnectionString))
{
SqlCommand cmd = new SqlCommand(storedProcedureName, conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter p = cmd.Parameters.AddWithValue(tableName, dt);
p.SqlDbType = SqlDbType.Structured;
p.TypeName = tableTypeName;
conn.Open();
int rowsAffected = cmd.ExecuteNonQuery(); // or could execute reader and pass a Func<T> to perform action on the datareader;
conn.Close();
return rowsAffected;
}
}
Sau đó, bạn có thể viết hàm DAL sử dụng chức năng tiện ích này với tên thực tế của các thủ tục được lưu trữ; để xây dựng trên các ví dụ trong câu hỏi của bạn, đây là những gì mã sẽ trông như thế:
public int usp_DoSomethingWithTableTypedParameter(List<UserID> userIdList)
{
DataTable dt = new DataTable();
dt.Columns.Add("UserId", typeof(int));
foreach (var userId in updateList)
{
dt.Rows.Add(new object[] { userId });
}
int rowsAffected = ExecStoredProcWithTVP(Connection, "usp_DoSomethingWithTableTypedParameter", "@UserIdList", "udt_UserId", dt);
return rowsAffected;
}
Lưu ý các "kết nối" tham số ở trên - Tôi thực sự sử dụng loại hàm trong một lớp DataContext một phần mở rộng LINQ DataContext với chức năng TVP của tôi, và vẫn sử dụng cú pháp (sử dụng var context = new MyDataContext()) với các phương thức này.
Điều này sẽ chỉ hoạt động nếu bạn đang sử dụng SQL Server 2008 - hy vọng bạn đang có và nếu không, đây có thể là một lý do tuyệt vời để nâng cấp! Tất nhiên trong hầu hết các trường hợp và môi trường sản xuất lớn này không phải là dễ dàng, nhưng FWIW tôi nghĩ rằng đây là cách tốt nhất để làm điều này nếu bạn có công nghệ có sẵn.
Các dấu phẩy phải giữa chuỗi, không nằm trong một chuỗi. –
Dấu phẩy tách biệt mỗi userid – chobo
Phiên bản SQL-Server nào? –