1
- using Kros . Data . BulkActions ;
1
+ using FluentAssertions ;
2
+ using Kros . Data . BulkActions ;
2
3
using Kros . Data . BulkActions . MsAccess ;
3
4
using Kros . Data . MsAccess ;
4
5
using Kros . UnitTests ;
6
+ using Kros . Utils . UnitTests ;
7
+ using Kros . Utils . UnitTests . Data . BulkActions ;
5
8
using Nito . AsyncEx ;
6
9
using System ;
7
10
using System . Collections . Generic ;
8
11
using System . Data ;
9
12
using System . Data . OleDb ;
13
+ using System . Diagnostics . CodeAnalysis ;
10
14
using System . IO ;
11
15
using System . Linq ;
12
16
using System . Reflection ;
13
17
using System . Threading . Tasks ;
14
18
using Xunit ;
15
19
16
- namespace Kros . Utils . UnitTests . Data . BulkActions
20
+ namespace Kros . Utils . MsAccess . UnitTests . Data . BulkActions
17
21
{
18
22
public class MsAccessBulkUpdateShould
19
23
{
@@ -32,13 +36,31 @@ private class BulkUpdateItem
32
36
public BulkUpdateItem Clone ( ) => ( BulkUpdateItem ) MemberwiseClone ( ) ;
33
37
}
34
38
39
+ private class BulkUpdateItemComposite
40
+ {
41
+ public int Id1 { get ; set ; }
42
+ public int Id2 { get ; set ; }
43
+ public string DataValue { get ; set ; }
44
+ public override bool Equals ( object obj )
45
+ {
46
+ if ( obj is BulkUpdateItemComposite item )
47
+ {
48
+ return ( Id1 == item . Id1 ) && ( Id2 == item . Id2 ) && ( DataValue == item . DataValue ) ;
49
+ }
50
+ return base . Equals ( obj ) ;
51
+ }
52
+ public override int GetHashCode ( )
53
+ => Id1 . GetHashCode ( ) ^ Id2 . GetHashCode ( ) ^ ( DataValue is null ? 0 : DataValue . GetHashCode ( ) ) ;
54
+ }
55
+
35
56
#endregion
36
57
37
58
#region Constants
38
59
39
60
private const string AccdbFileName = "MsAccessBulkUpdate.accdb" ;
40
61
private const string MdbFileName = "MsAccessBulkUpdate.mdb" ;
41
62
private const string TableName = "BulkUpdateTest" ;
63
+ private const string Composite_TableName = "BulkUpdateTestCompositePK" ;
42
64
private const string PrimaryKeyColumn = "Id" ;
43
65
private const string ShortTextAction = "dolor sit amet" ;
44
66
private const double DoubleMinimum = - 999999999999999999999.999999999999 ;
@@ -83,6 +105,74 @@ private void DataTableBulkUpdateCore(OleDbConnection cn)
83
105
MsAccessBulkHelper . CompareTables ( actualData , expectedData ) ;
84
106
}
85
107
108
+ [ SkippableFact ]
109
+ public async Task BulkUpdateDataWithCompositePkAccdb ( )
110
+ {
111
+ Helpers . SkipTestIfAceProviderNotAvailable ( ) ;
112
+ using ( var helper = CreateHelper ( ProviderType . Ace , AccdbFileName ) )
113
+ {
114
+ await BulkUpdateDataWithCompositePk ( helper . Connection ) ;
115
+ }
116
+ }
117
+
118
+ [ SkippableFact ]
119
+ public async Task BulkUpdateDataWithCompositePkMdb ( )
120
+ {
121
+ Helpers . SkipTestIfJetProviderNotAvailable ( ) ;
122
+ using ( var helper = CreateHelper ( ProviderType . Jet , MdbFileName ) )
123
+ {
124
+ await BulkUpdateDataWithCompositePk ( helper . Connection ) ;
125
+ }
126
+ }
127
+
128
+ private async Task BulkUpdateDataWithCompositePk ( OleDbConnection cn )
129
+ {
130
+ List < BulkUpdateItemComposite > actualData = null ;
131
+
132
+ using ( var bulkUpdate = new MsAccessBulkUpdate ( cn ) )
133
+ {
134
+ var dataToUpdate = new EnumerableDataReader < BulkUpdateItemComposite > (
135
+ new [ ] {
136
+ new BulkUpdateItemComposite ( ) { Id1 = 1 , Id2 = 2 , DataValue = "lorem ipsum 1" } ,
137
+ new BulkUpdateItemComposite ( ) { Id1 = 2 , Id2 = 2 , DataValue = "lorem ipsum 2" } ,
138
+ new BulkUpdateItemComposite ( ) { Id1 = 3 , Id2 = 2 , DataValue = "lorem ipsum 3" }
139
+ } ,
140
+ new [ ] { nameof ( BulkUpdateItemComposite . Id1 ) , nameof ( BulkUpdateItemComposite . Id2 ) , nameof ( BulkUpdateItemComposite . DataValue ) } ) ;
141
+
142
+ bulkUpdate . DestinationTableName = Composite_TableName ;
143
+ bulkUpdate . PrimaryKeyColumn = nameof ( BulkUpdateItemComposite . Id1 ) + ", " + nameof ( BulkUpdateItemComposite . Id2 ) ;
144
+ await bulkUpdate . UpdateAsync ( dataToUpdate ) ;
145
+
146
+ actualData = LoadDataForTableWithCompositePk ( cn , Composite_TableName ) ;
147
+ }
148
+
149
+ actualData . Should ( ) . Equal ( new List < BulkUpdateItemComposite > ( new [ ]
150
+ {
151
+ new BulkUpdateItemComposite ( ) { Id1 = 1 , Id2 = 1 , DataValue = "1 - 1" } ,
152
+ new BulkUpdateItemComposite ( ) { Id1 = 1 , Id2 = 2 , DataValue = "lorem ipsum 1" } ,
153
+ new BulkUpdateItemComposite ( ) { Id1 = 2 , Id2 = 1 , DataValue = "2 - 1" } ,
154
+ new BulkUpdateItemComposite ( ) { Id1 = 2 , Id2 = 2 , DataValue = "lorem ipsum 2" } ,
155
+ new BulkUpdateItemComposite ( ) { Id1 = 3 , Id2 = 1 , DataValue = "3 - 1" } ,
156
+ new BulkUpdateItemComposite ( ) { Id1 = 3 , Id2 = 2 , DataValue = "lorem ipsum 3" } ,
157
+ } ) ) ;
158
+ }
159
+
160
+ [ SuppressMessage ( "Security" , "CA2100:Review SQL queries for security vulnerabilities" ) ]
161
+ private List < BulkUpdateItemComposite > LoadDataForTableWithCompositePk ( OleDbConnection cn , string tableName )
162
+ {
163
+ var data = new List < BulkUpdateItemComposite > ( ) ;
164
+
165
+ using ( var cmd = new OleDbCommand ( $ "SELECT [Id1], [Id2], [DataValue] FROM [{ tableName } ] ORDER BY [Id1], [Id2]", cn ) )
166
+ using ( var reader = cmd . ExecuteReader ( ) )
167
+ {
168
+ while ( reader . Read ( ) )
169
+ {
170
+ data . Add ( new BulkUpdateItemComposite ( ) { Id1 = reader . GetInt32 ( 0 ) , Id2 = reader . GetInt32 ( 1 ) , DataValue = reader . GetString ( 2 ) } ) ;
171
+ }
172
+ }
173
+ return data ;
174
+ }
175
+
86
176
[ SkippableFact ]
87
177
public void BulkUpdateDataFromIBulkActionDataReaderIntoAccdb ( )
88
178
{
0 commit comments