Quantcast
Channel: Brian Pedersen's Sitecore and .NET Blog
Viewing all articles
Browse latest Browse all 285

C# SqlBulkCopy insert a list of objects

$
0
0

The SqlBulkCopy class is able to bulk insert data from anything that comes from a DataTable or can be read using a SqlDataReader.

So what do you do if you have an array of objects?

You have to convert the array into a DataTable, then call SqlBulkCopy.

First of all, this is my table:

CREATE TABLE [dbo].[Favorites](
    [rowId] [int] IDENTITY(1,1) NOT NULL,
    [userKey] [int] NOT NULL,
    [favoriteId] [nvarchar](255) NULL,
    [lastModified] [datetime] NULL,
    [isDeleted] [bit] NULL,
    [created] [datetime] NULL,
 CONSTRAINT [PK_Favorites] PRIMARY KEY CLUSTERED 
(
    [rowID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

I have mapped the table into a DTO. Please notice that names AND THE ORDER of the fields in the DTO matches the names order of the fields in the SQL table:

public class FavoriteDTO
{
    public int RowId { get; set; } 
    public int UserKey { get; set; } 
    public string FavoriteId { get; set; } 
    public DateTime? LastModified { get; set; } 
    public bool? IsDeleted { get; set; } 
    public DateTime? Created { get; set; } 
}

STEP 1: CONVERT THE DTO INTO A DATATABLE

First we must convert the array of FavoriteDTO into a DataTable. This extension method will take care of that:

using System.ComponentModel;
using System.Data;
 
namespace MyCode
{
  public static class IEnumerableExtensions
  {
    public static DataTable ToDataTable<T>(this IEnumerable<T> data)
    {
      PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
      DataTable table = new DataTable();
      foreach (PropertyDescriptor prop in properties)
      {
        table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
      }
      foreach (T item in data)
      {
        DataRow row = table.NewRow();
        foreach (PropertyDescriptor prop in properties)
          row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
        table.Rows.Add(row);
      }
      return table;
    }
  }
}

STEP 2: THE BULKCOPY METHOD

This BulkInsertAsync method will call the ToDataTable() extension method before calling WriteToServerAsync, allowing us to insert the objects in bulk.

using Microsoft.Data.SqlClient;

public async Task BulkInsertAsync(IEnumerable<FavoriteDTO> favorites)
{
    try
    {
        using var connection = new SqlConnection("your connection string");
        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
        {
            connection.Open();
            bulkCopy.DestinationTableName = "Favorites";
            await bulkCopy.WriteToServerAsync(favorites.ToDataTable());
        }
    }
    catch (SqlException e)
    {
        throw new Exception($"Failed to insert favorites: {e.Message}", e);
    }
}

That’s it. Happy coding.

MORE TO READ:


Viewing all articles
Browse latest Browse all 285

Trending Articles