-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
132 lines (100 loc) · 4.73 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using System.Data;
using System.Data.SqlClient;
class Program
{
static async Task Main()
{
string tableName = "Customers";
string soutceConnectionString = "Integrated Security=SSPI;Persist Security Info=False;User ID=admin;Initial Catalog=MyDB;Data Source=.";
string targetConnectionString = "Integrated Security=SSPI;Persist Security Info=False;User ID=admin;Initial Catalog=MyDB2;Data Source=.";
// 1st create 2 databases MyDB and MyDB2
// include this line to set up the tables on the 1st run of this code
await CreateTablesAndPopulateSource(tableName, soutceConnectionString, targetConnectionString);
await SyncTables(tableName, soutceConnectionString, targetConnectionString);
}
static async Task SyncTables(string tableName, string sourceConnection, string targetConnection)
{
int timeout = 999;
// Open a sourceConnection to the MyDB database.
using SqlConnection sourceCon = new(sourceConnection);
await sourceCon.OpenAsync();
SqlDataReader reader;
using (SqlCommand cmd = new($"SELECT * FROM {tableName}", sourceCon))
{
reader = await cmd.ExecuteReaderAsync();
}
using SqlConnection destinationConnection = new(targetConnection);
// check for a possible config issue, source and target should not be the same table
if (sourceCon.DataSource.Equals(destinationConnection.DataSource, StringComparison.OrdinalIgnoreCase)
&& sourceCon.Database.Equals(destinationConnection.Database, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("The source and destination tables is the same table on the same sql instance.");
}
await destinationConnection.OpenAsync();
using SqlTransaction transaction = destinationConnection.BeginTransaction();
using (SqlCommand cmd = new($"truncate table {tableName}", destinationConnection, transaction))
{
cmd.CommandTimeout = timeout;
await cmd.ExecuteNonQueryAsync();
}
using SqlBulkCopy bulkCopy = new(destinationConnection, SqlBulkCopyOptions.KeepIdentity, transaction);
bulkCopy.EnableStreaming = true;
bulkCopy.DestinationTableName = tableName;
bulkCopy.BulkCopyTimeout = timeout;
try
{
// Write from the source to the destination.
await bulkCopy.WriteToServerAsync(reader);
await transaction.CommitAsync();
}
catch (Exception)
{
transaction.Rollback();
}
finally
{
// Close the SqlDataReader
await reader.CloseAsync();
await sourceCon.CloseAsync();
}
}
private static async Task CreateTablesAndPopulateSource(string tableName, string soutceConnectionString, string targetConnectionString)
{
string cmdText = $@"CREATE TABLE [dbo].[{tableName}] (
[Id][uniqueidentifier] ROWGUIDCOL NOT NULL
CONSTRAINT[PK_Customers] PRIMARY KEY CLUSTERED,
[LastName] [nvarchar](255) NULL,
[FirstName] [nvarchar](255) NULL,
[Street] [nvarchar](255) NULL,
[City] [nvarchar](255) NULL,
[State] [nvarchar](255) NULL,
[PhoneNumber] [nvarchar](255) NULL,
[EmailAddress] [nvarchar](255) NULL
)";
using (SqlConnection sourceCon = new(soutceConnectionString))
{
var command = new SqlCommand(cmdText, sourceCon);
await sourceCon.OpenAsync();
await command.ExecuteNonQueryAsync();
command.CommandText = $"SELECT * FROM [{tableName}]";
SqlDataAdapter adapter = new(command);
DataTable dt = new();
await Task.Run(() => adapter.Fill(dt));
for (int i = 0; i < 100000; i++)
{
dt.Rows.Add(new object[] { Guid.NewGuid().ToString(), "f", "l", "s", "c", "st", 123, "asd" });
}
using var copy = new SqlBulkCopy(sourceCon);
copy.DestinationTableName = tableName;
await copy.WriteToServerAsync(dt);
await sourceCon.CloseAsync();
}
using (SqlConnection targetConnection = new(targetConnectionString))
{
var command = new SqlCommand(cmdText, targetConnection);
await targetConnection.OpenAsync();
await command.ExecuteNonQueryAsync();
await targetConnection.CloseAsync();
}
}
}