1+ using System . Data ;
2+ using System . Data . Common ;
3+ using EfCore . BulkOperations . API . Models ;
4+ using Microsoft . EntityFrameworkCore ;
5+ using Microsoft . EntityFrameworkCore . Storage ;
6+
7+ namespace EfCore . BulkOperations . API . Repositories ;
8+
9+ public class ProductRepository ( ApplicationDbContext dbContext ) : IProductRepository
10+ {
11+ public async Task < Product ? > GetProduct ( Guid id )
12+ {
13+ return await dbContext
14+ . Products
15+ . Where ( x => x . Id == id )
16+ . FirstOrDefaultAsync ( ) ;
17+ }
18+
19+ public async Task < List < Product > > GetProducts ( )
20+ {
21+ return await dbContext . Products . ToListAsync ( ) ;
22+ }
23+
24+ public async Task < int > InsertProducts ( List < Product > products )
25+ {
26+ var rowAffected = await dbContext . BulkInsertAsync (
27+ products ,
28+ option => { option . UniqueKeys = x => new { x . Id } ; } ) ;
29+ return rowAffected ;
30+ }
31+
32+ public async Task < int > UpdateProducts ( List < Product > products )
33+ {
34+ var rowAffected = await dbContext . BulkUpdateAsync (
35+ products ,
36+ option => { option . UniqueKeys = x => new { x . Id } ; } ) ;
37+ return rowAffected ;
38+ }
39+
40+ public async Task < int > DeleteProducts ( List < Product > products )
41+ {
42+ var rowAffected = await dbContext . BulkDeleteAsync (
43+ products ,
44+ option => { option . UniqueKeys = x => new { x . Id } ; } ) ;
45+ return rowAffected ;
46+ }
47+
48+ public async Task < int > MergeProducts ( List < Product > products )
49+ {
50+ var rowAffected = await dbContext . BulkMergeAsync (
51+ products ,
52+ option => { option . UniqueKeys = x => new { x . Id } ; } ) ;
53+ return rowAffected ;
54+ }
55+
56+ public async Task SyncDataThenCommit ( List < Product > list1 , List < Product > list2 )
57+ {
58+ IDbContextTransaction ? transaction = null ;
59+ DbConnection ? connection = null ;
60+ try
61+ {
62+ connection = dbContext . Database . GetDbConnection ( ) ;
63+ if ( connection . State != ConnectionState . Open ) await connection . OpenAsync ( ) ;
64+ transaction = await dbContext . Database . BeginTransactionAsync ( ) ;
65+ var dbTransaction = transaction . GetDbTransaction ( ) ;
66+
67+ await dbContext . BulkInsertAsync ( list1 , null , dbTransaction ) ;
68+ await dbContext . BulkInsertAsync ( list2 , null , dbTransaction ) ;
69+
70+ await transaction . CommitAsync ( ) ;
71+ }
72+ catch ( Exception )
73+ {
74+ if ( transaction is not null ) await transaction . RollbackAsync ( ) ;
75+ throw ;
76+ }
77+ finally
78+ {
79+ if ( connection is { State : ConnectionState . Open } ) await connection . CloseAsync ( ) ;
80+ }
81+ }
82+
83+ public async Task SyncDataThenRollback ( Product item1 , List < Product > list2 , List < Product > list3 )
84+ {
85+ IDbContextTransaction ? transaction = null ;
86+ DbConnection ? connection = null ;
87+ try
88+ {
89+ connection = dbContext . Database . GetDbConnection ( ) ;
90+ if ( connection . State != ConnectionState . Open ) await connection . OpenAsync ( ) ;
91+ transaction = await dbContext . Database . BeginTransactionAsync ( ) ;
92+ var dbTransaction = transaction . GetDbTransaction ( ) ;
93+
94+ dbContext . Products . Add ( item1 ) ;
95+ await dbContext . SaveChangesAsync ( ) ;
96+ await dbContext . BulkInsertAsync ( list2 , null , dbTransaction ) ;
97+ await dbContext . BulkInsertAsync ( list3 , null , dbTransaction ) ;
98+
99+ throw new DbUpdateException ( "Internal Server Error" ) ;
100+ }
101+ catch ( Exception )
102+ {
103+ if ( transaction is not null ) await transaction . RollbackAsync ( ) ;
104+ throw ;
105+ }
106+ finally
107+ {
108+ if ( connection is { State : ConnectionState . Open } ) await connection . CloseAsync ( ) ;
109+ }
110+ }
111+ }
0 commit comments