Skip to content

Instantly share code, notes, and snippets.

@nikyodo85
Created September 28, 2018 18:27
Show Gist options
  • Save nikyodo85/b82ffd56bb2f0d45a9860dadcdfdc01d to your computer and use it in GitHub Desktop.
Save nikyodo85/b82ffd56bb2f0d45a9860dadcdfdc01d to your computer and use it in GitHub Desktop.
Allow inserting Entity Framework entities to the database using SqlBulkCopy
Imports System.ComponentModel.DataAnnotations.Schema
Imports System.Data.Common
Imports System.Data.Entity.Core.Metadata
Imports System.Reflection
Imports System.Data.Entity
Public Class EFSqlBulkCopy(Of T As Class)
Public Property DestinationTableName As String
Private type As Type = GetType(T)
Private properties As PropertyInfo() = type.GetProperties()
Private connection As DbConnection
Sub New(dbConnection As DbConnection)
connection = dbConnection
End Sub
Sub New(dbContext As DbContext)
connection = dbContext.Database.Connection
End Sub
Public Sub WriteToServer(enumerable As IEnumerable(Of T))
Using sqlBulkCopy As New SqlBulkCopy(connection)
If String.IsNullOrWhiteSpace(DestinationTableName) Then
If type.CustomAttributes.Any(Function(a) a.AttributeType = GetType(TableAttribute)) Then
Dim tableAttribute = type.GetCustomAttribute(Of TableAttribute)
sqlBulkCopy.DestinationTableName = tableAttribute.Name
Else
sqlBulkCopy.DestinationTableName = type.Name
End If
Else
sqlBulkCopy.DestinationTableName = DestinationTableName
End If
Dim propertyColumnMapping As New Dictionary(Of String, String)
Dim dataTable As New DataTable
For Each p In properties
If p.CustomAttributes.Any(Function(a) a.AttributeType = GetType(NotMappedAttribute)) Then
Continue For
ElseIf p.CustomAttributes.Any(Function(a) a.AttributeType = GetType(ColumnAttribute)) Then
Dim columnAttribute = p.GetCustomAttribute(Of ColumnAttribute)
dataTable.Columns.Add(New DataColumn(columnAttribute.Name, p.PropertyType))
propertyColumnMapping.Add(p.Name, columnAttribute.Name)
ElseIf p.SetMethod IsNot Nothing AndAlso p.GetMethod IsNot Nothing AndAlso
Edm.PrimitiveType.GetEdmPrimitiveTypes().Any(Function(pt) pt.ClrEquivalentType = p.PropertyType) Then
dataTable.Columns.Add(New DataColumn(p.Name, p.PropertyType))
propertyColumnMapping.Add(p.Name, p.Name)
End If
Next
For Each element In enumerable
Dim dataRow = dataTable.NewRow()
For Each p In properties
If propertyColumnMapping.ContainsKey(p.Name) Then
dataRow(propertyColumnMapping(p.Name)) = p.GetValue(element)
End If
Next
dataTable.Rows.Add(dataRow)
Next
If connection.State = ConnectionState.Closed Then
connection.Open()
End If
sqlBulkCopy.WriteToServer(dataTable)
connection.Close()
End Using
End Sub
End Class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment