I think you can try these two ways:
- Without a stored procedure: You can try with SqlBulkCopy class.
C# Code:
static void Main(string[] args)
{
Console.WriteLine("Inserting ...");
var userId = 777;
var productIds = new List<int> { 1, 2, 3, 4 };
var dto = new Dictionary<int, List<int>>
{
{ userId, productIds }
};
ExecuteBulkInsert(dto);
// ExecuteProcedure(dto);
Console.WriteLine("Done! ...");
Console.ReadLine();
}
public static void ExecuteBulkInsert( Dictionary<int, List<int>> dto)
{
string connectionString = GetConnectionString();
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
DataTable newProducts = CreateDataTable(dto);
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
bulkCopy.DestinationTableName = "dbo.UserProducts";
bulkCopy.WriteToServer(newProducts);
}
}
}
private static DataTable CreateDataTable(Dictionary<int, List<int>> dto)
{
const string IdUserColumnName = "IdUser";
const string IdProductColumnName = "IdProduct";
DataTable table = new DataTable();
table.Columns.Add(new DataColumn(IdUserColumnName, typeof(int)));
table.Columns.Add(new DataColumn(IdProductColumnName, typeof(int)));
foreach (var product in dto)
{
foreach (var productId in product.Value)
table.Rows.Add(product.Key, productId);
}
return table;
}
- With a stored procedure: Try with a table-valued parameter
SQL Code:
CREATE TABLE dbo.UserProducts
(
IdUser INT NOT NULL,
IdProduct INT NOT NULL
);
GO
CREATE TYPE dbo.UserProductsType AS TABLE
(
IdUser INT NOT NULL,
IdUser INT NOT NULL
);
GO
CREATE PROCEDURE dbo.UserProductsInsert
@userProductsType dbo.UserProductsType READONLY
AS
BEGIN
INSERT INTO UserProducts
SELECT * FROM @userProductsType
END
C# Code:
private static void ExecuteProcedure( Dictionary<int, List<int>> dto)
{
string connectionString = GetConnectionString();
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "dbo.UserProductsInsert";
command.CommandType = CommandType.StoredProcedure;
SqlParameter parameter = command.Parameters.AddWithValue("@userProductsType", CreateDataTable(dto));
parameter.SqlDbType = SqlDbType.Structured;
parameter.TypeName = "dbo.UserProductsType";
command.ExecuteNonQuery();
}
}
}