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