diff --git a/.nuget/NuGet.Config b/.nuget/NuGet.Config
new file mode 100644
index 0000000..67f8ea0
--- /dev/null
+++ b/.nuget/NuGet.Config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.nuget/NuGet.exe b/.nuget/NuGet.exe
new file mode 100644
index 0000000..8dd7e45
Binary files /dev/null and b/.nuget/NuGet.exe differ
diff --git a/.nuget/NuGet.targets b/.nuget/NuGet.targets
new file mode 100644
index 0000000..3f8c37b
--- /dev/null
+++ b/.nuget/NuGet.targets
@@ -0,0 +1,144 @@
+
+
+
+ $(MSBuildProjectDirectory)\..\
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+ $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
+
+
+
+
+ $(SolutionDir).nuget
+
+
+
+ $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config
+ $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config
+
+
+
+ $(MSBuildProjectDirectory)\packages.config
+ $(PackagesProjectConfig)
+
+
+
+
+ $(NuGetToolsPath)\NuGet.exe
+ @(PackageSource)
+
+ "$(NuGetExePath)"
+ mono --runtime=v4.0.30319 "$(NuGetExePath)"
+
+ $(TargetDir.Trim('\\'))
+
+ -RequireConsent
+ -NonInteractive
+
+ "$(SolutionDir) "
+ "$(SolutionDir)"
+
+
+ $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)
+ $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols
+
+
+
+ RestorePackages;
+ $(BuildDependsOn);
+
+
+
+
+ $(BuildDependsOn);
+ BuildPackage;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Demo/App.config b/Demo/App.config
new file mode 100644
index 0000000..c774a25
--- /dev/null
+++ b/Demo/App.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Demo/Demo.csproj b/Demo/Demo.csproj
new file mode 100644
index 0000000..28a5c93
--- /dev/null
+++ b/Demo/Demo.csproj
@@ -0,0 +1,65 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {ED5A2A14-E41C-4094-B81D-D4AF52699D8F}
+ Exe
+ Properties
+ Demo
+ Demo
+ v4.5.1
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {535f1a7b-53f8-4323-a1ea-44efdc57b3fa}
+ Logic
+
+
+
+
+
\ No newline at end of file
diff --git a/Demo/Program.cs b/Demo/Program.cs
new file mode 100644
index 0000000..8315636
--- /dev/null
+++ b/Demo/Program.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Data.SqlClient;
+using System.Linq;
+
+namespace Demo
+{
+ internal class Program
+ {
+ private static void Main(string[] args)
+ {
+ var rand = new Random();
+ var randomNumbers = new List();
+ for (int i = 0; i < 5000; i++)
+ {
+ randomNumbers.Add(rand.Next());
+ }
+
+ using (var ssbc = new SimpleSqlBulkCopy("ConnectionString"))
+ {
+ ssbc.WriteToServer("TableName", randomNumbers.Select(rn => new { Score = rn }));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Demo/Properties/AssemblyInfo.cs b/Demo/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..3e39eb6
--- /dev/null
+++ b/Demo/Properties/AssemblyInfo.cs
@@ -0,0 +1,39 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("Demo")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Demo")]
+[assembly: AssemblyCopyright("Copyright © 2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("c342306e-f921-459d-9788-c07124dc0e99")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
diff --git a/Logic/Logic.csproj b/Logic/Logic.csproj
new file mode 100644
index 0000000..3bfb8f3
--- /dev/null
+++ b/Logic/Logic.csproj
@@ -0,0 +1,53 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {535F1A7B-53F8-4323-A1EA-44EFDC57B3FA}
+ Library
+ Properties
+ System.Data.SqlClient
+ SimpleSqlBulkCopy
+ v4.5.1
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Logic/Properties/AssemblyInfo.cs b/Logic/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d78a2e7
--- /dev/null
+++ b/Logic/Properties/AssemblyInfo.cs
@@ -0,0 +1,39 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("Logic")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Logic")]
+[assembly: AssemblyCopyright("Copyright © 2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("e9f385cb-3b0d-4af7-92b5-5a158564c825")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
diff --git a/Logic/SimpleSqlBulkCopy.cs b/Logic/SimpleSqlBulkCopy.cs
new file mode 100644
index 0000000..c23e9bd
--- /dev/null
+++ b/Logic/SimpleSqlBulkCopy.cs
@@ -0,0 +1,153 @@
+using System.Collections.Generic;
+using System.Reflection;
+using System.Threading.Tasks;
+
+namespace System.Data.SqlClient
+{
+ public class SimpleSqlBulkCopy : IDisposable
+ {
+ private SqlBulkCopy sqlBulkCopy;
+
+ ///
+ /// Initializes a new instance of the class using the specified open
+ /// instance of .
+ ///
+ ///
+ /// The already open instance that will be
+ /// used to perform the bulk copy operation. If your connection string does not use Integrated Security = true, you can
+ /// use to pass the user ID and password more securely than by
+ /// specifying the user ID and password as text in the connection string.
+ ///
+ public SimpleSqlBulkCopy(SqlConnection connection)
+ {
+ sqlBulkCopy = new SqlBulkCopy(connection);
+ }
+
+ ///
+ /// Initializes a new instance of the class using the supplied
+ /// existing open instance of . The
+ /// instance behaves according to options supplied in the
+ /// parameter. If a non-null is
+ /// supplied, the copy operations will be performed within that transaction.
+ ///
+ ///
+ /// The already open instance that will be
+ /// used to perform the bulk copy. If your connection string does not use Integrated Security = true, you can use
+ /// to pass the user ID and password more securely than by
+ /// specifying the user ID and password as text in the connection string.
+ ///
+ ///
+ /// A combination of values from the
+ /// enumeration that determines which data source rows are copied to the destination table.
+ ///
+ ///
+ /// An existing instance under
+ /// which the bulk copy will occur.
+ ///
+ public SimpleSqlBulkCopy(SqlConnection connection, SqlBulkCopyOptions copyOptions,
+ SqlTransaction externalTransaction)
+ {
+ sqlBulkCopy = new SqlBulkCopy(connection, copyOptions, externalTransaction);
+ }
+
+ ///
+ /// Initializes and opens a new instance of based on the supplied
+ /// . The constructor uses the
+ /// to initialize a new instance of the class.
+ ///
+ ///
+ /// The string defining the connection that will be opened for use by the
+ /// instance. If your connection string does not use Integrated
+ /// Security = true, you can use
+ /// or
+ ///
+ /// and to pass the user ID and password more securely than by
+ /// specifying the user ID and password as text in the connection string.
+ ///
+ public SimpleSqlBulkCopy(string connectionString)
+ {
+ sqlBulkCopy = new SqlBulkCopy(connectionString);
+ }
+
+ ///
+ /// Initializes and opens a new instance of based on the supplied
+ /// . The constructor uses that
+ /// to initialize a new instance of the
+ /// class. The
+ /// instance behaves according to options supplied in the parameter.
+ ///
+ ///
+ /// The string defining the connection that will be opened for use by the
+ /// instance. If your connection string does not use Integrated
+ /// Security = true, you can use
+ /// or
+ ///
+ /// and to pass the user ID and password more securely than by
+ /// specifying the user ID and password as text in the connection string.
+ ///
+ ///
+ /// A combination of values from the
+ /// enumeration that determines which data source rows are copied to the destination table.
+ ///
+ public SimpleSqlBulkCopy(string connectionString, SqlBulkCopyOptions copyOptions)
+ {
+ sqlBulkCopy = new SqlBulkCopy(connectionString, copyOptions);
+ }
+
+ public SqlBulkCopy SqlBulkCopy
+ {
+ get { return sqlBulkCopy; }
+ }
+
+ public void Dispose()
+ {
+ sqlBulkCopy = null;
+ }
+
+
+ public void WriteToServer(string destinationTableName, IEnumerable data)
+ {
+ sqlBulkCopy.DestinationTableName = destinationTableName;
+ DataTable dt = getDataTableFromFields(data);
+
+ sqlBulkCopy.WriteToServer(dt);
+ }
+
+ public async Task WriteToServerAsync(string destinationTableName, IEnumerable data)
+ {
+ sqlBulkCopy.DestinationTableName = destinationTableName;
+ DataTable dt = getDataTableFromFields(data);
+
+ await sqlBulkCopy.WriteToServerAsync(dt);
+ }
+
+ private DataTable getDataTableFromFields(IEnumerable data)
+ {
+ var dt = new DataTable();
+
+ Type listType = typeof (T);
+
+ foreach (PropertyInfo propertyInfo in listType.GetProperties())
+ {
+ dt.Columns.Add(propertyInfo.Name, propertyInfo.PropertyType);
+ sqlBulkCopy.ColumnMappings.Add(propertyInfo.Name, propertyInfo.Name);
+ }
+
+ foreach (T value in data)
+ {
+ DataRow dr = dt.NewRow();
+
+ foreach (PropertyInfo propertyInfo in listType.GetProperties())
+ {
+ dr[propertyInfo.Name] = propertyInfo.GetValue(value, null);
+ }
+
+ dt.Rows.Add(dr);
+ }
+
+ return dt;
+ }
+ }
+}
\ No newline at end of file
diff --git a/SimpleSqlBulkCopy.sln b/SimpleSqlBulkCopy.sln
new file mode 100644
index 0000000..aff40bd
--- /dev/null
+++ b/SimpleSqlBulkCopy.sln
@@ -0,0 +1,41 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.31101.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{0864C646-9FCB-46C9-8CBB-2C8FCFD4DAD7}"
+ ProjectSection(SolutionItems) = preProject
+ .nuget\NuGet.Config = .nuget\NuGet.Config
+ .nuget\NuGet.exe = .nuget\NuGet.exe
+ .nuget\NuGet.targets = .nuget\NuGet.targets
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9E38BA4A-B404-451B-B129-A1890FF7C757}"
+ ProjectSection(SolutionItems) = preProject
+ LICENSE = LICENSE
+ README.md = README.md
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logic", "Logic\Logic.csproj", "{535F1A7B-53F8-4323-A1EA-44EFDC57B3FA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo", "Demo\Demo.csproj", "{ED5A2A14-E41C-4094-B81D-D4AF52699D8F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {535F1A7B-53F8-4323-A1EA-44EFDC57B3FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {535F1A7B-53F8-4323-A1EA-44EFDC57B3FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {535F1A7B-53F8-4323-A1EA-44EFDC57B3FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {535F1A7B-53F8-4323-A1EA-44EFDC57B3FA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ED5A2A14-E41C-4094-B81D-D4AF52699D8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ED5A2A14-E41C-4094-B81D-D4AF52699D8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ED5A2A14-E41C-4094-B81D-D4AF52699D8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ED5A2A14-E41C-4094-B81D-D4AF52699D8F}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal