@@ -12,25 +12,60 @@ namespace PhenX.EntityFrameworkCore.BulkInsert.Extensions;
1212public static class DbSetExtensions
1313{
1414 /// <summary>
15- /// Executes a bulk insert operation returning the inserted/updated entities, from the DbSet.
15+ /// Executes a bulk insert operation returning the inserted/updated entities, from the DbSet, with options which
16+ /// can be a subclass of <see cref="BulkInsertOptions"/>.
1617 /// </summary>
17- public static async Task < List < T > > ExecuteBulkInsertReturnEntitiesAsync < T > (
18+ public static async Task < List < T > > ExecuteBulkInsertReturnEntitiesAsync < T , TOptions > (
1819 this DbSet < T > dbSet ,
1920 IEnumerable < T > entities ,
20- Action < BulkInsertOptions > ? configure = null ,
21+ Action < TOptions > configure ,
2122 OnConflictOptions ? onConflict = null ,
2223 CancellationToken ctk = default
23- ) where T : class
24+ )
25+ where T : class
26+ where TOptions : BulkInsertOptions
2427 {
2528 var provider = InitProvider ( dbSet , configure , out var context , out var options ) ;
2629
2730 return await provider . BulkInsertReturnEntities ( false , context , entities , options , onConflict , ctk ) ;
2831 }
2932
33+ /// <summary>
34+ /// Executes a bulk insert operation returning the inserted/updated entities, from the DbSet without options.
35+ /// </summary>
36+ public static async Task < List < T > > ExecuteBulkInsertReturnEntitiesAsync < T > (
37+ this DbSet < T > dbSet ,
38+ IEnumerable < T > entities ,
39+ Action < BulkInsertOptions > configure ,
40+ OnConflictOptions ? onConflict = null ,
41+ CancellationToken ctk = default
42+ ) where T : class
43+ => await ExecuteBulkInsertReturnEntitiesAsync < T , BulkInsertOptions > ( dbSet , entities , configure , onConflict , ctk ) ;
44+
45+
46+ /// <summary>
47+ /// Executes a bulk insert operation returning the inserted/updated entities, from the DbSet without options.
48+ /// </summary>
49+ public static async Task < List < T > > ExecuteBulkInsertReturnEntitiesAsync < T > (
50+ this DbSet < T > dbSet ,
51+ IEnumerable < T > entities ,
52+ OnConflictOptions ? onConflict = null ,
53+ CancellationToken ctk = default
54+ ) where T : class
55+ => await ExecuteBulkInsertReturnEntitiesAsync < T , BulkInsertOptions > ( dbSet , entities , _ => { } , onConflict , ctk ) ;
56+
3057 /// <summary>
3158 /// Executes a bulk insert operation returning the inserted/updated entities, from the DbContext.
3259 /// </summary>
33- public static async Task < List < T > > ExecuteBulkInsertReturnEntitiesAsync < T > ( this DbContext dbContext , IEnumerable < T > entities , Action < BulkInsertOptions > ? configure = null , OnConflictOptions ? onConflict = null , CancellationToken cancellationToken = default ) where T : class
60+ public static async Task < List < T > > ExecuteBulkInsertReturnEntitiesAsync < T , TOptions > (
61+ this DbContext dbContext ,
62+ IEnumerable < T > entities ,
63+ Action < TOptions > configure ,
64+ OnConflictOptions ? onConflict = null ,
65+ CancellationToken cancellationToken = default
66+ )
67+ where T : class
68+ where TOptions : BulkInsertOptions
3469 {
3570 var dbSet = dbContext . Set < T > ( ) ;
3671 if ( dbSet == null )
@@ -41,16 +76,41 @@ public static async Task<List<T>> ExecuteBulkInsertReturnEntitiesAsync<T>(this D
4176 return await dbSet . ExecuteBulkInsertReturnEntitiesAsync ( entities , configure , onConflict , cancellationToken ) ;
4277 }
4378
79+ /// <summary>
80+ /// Executes a bulk insert operation returning the inserted/updated entities, from the DbContext, with generic options.
81+ /// </summary>
82+ public static async Task < List < T > > ExecuteBulkInsertReturnEntitiesAsync < T > (
83+ this DbContext dbContext ,
84+ IEnumerable < T > entities ,
85+ Action < BulkInsertOptions > configure ,
86+ OnConflictOptions ? onConflict = null ,
87+ CancellationToken cancellationToken = default
88+ ) where T : class
89+ => await ExecuteBulkInsertReturnEntitiesAsync < T , BulkInsertOptions > ( dbContext , entities , configure , onConflict , cancellationToken ) ;
90+
91+ /// <summary>
92+ /// Executes a bulk insert operation returning the inserted/updated entities, from the DbContext, with generic options.
93+ /// </summary>
94+ public static async Task < List < T > > ExecuteBulkInsertReturnEntitiesAsync < T > (
95+ this DbContext dbContext ,
96+ IEnumerable < T > entities ,
97+ OnConflictOptions ? onConflict = null ,
98+ CancellationToken cancellationToken = default
99+ ) where T : class =>
100+ await dbContext . ExecuteBulkInsertReturnEntitiesAsync < T , BulkInsertOptions > ( entities , _ => { } , onConflict , cancellationToken ) ;
101+
44102 /// <summary>
45103 /// Executes a bulk insert operation without returning the inserted/updated entities, from the DbSet.
46104 /// </summary>
47- public static async Task ExecuteBulkInsertAsync < T > (
105+ public static async Task ExecuteBulkInsertAsync < T , TOptions > (
48106 this DbSet < T > dbSet ,
49107 IEnumerable < T > entities ,
50- Action < BulkInsertOptions > ? configure = null ,
108+ Action < TOptions > configure ,
51109 OnConflictOptions ? onConflict = null ,
52110 CancellationToken ctk = default
53- ) where T : class
111+ )
112+ where T : class
113+ where TOptions : BulkInsertOptions
54114 {
55115 var provider = InitProvider ( dbSet , configure , out var context , out var options ) ;
56116
@@ -60,7 +120,14 @@ public static async Task ExecuteBulkInsertAsync<T>(
60120 /// <summary>
61121 /// Executes a bulk insert operation without returning the inserted/updated entities, from the DbContext.
62122 /// </summary>
63- public static async Task ExecuteBulkInsertAsync < T > ( this DbContext dbContext , IEnumerable < T > entities , Action < BulkInsertOptions > ? configure = null , OnConflictOptions ? onConflict = null , CancellationToken cancellationToken = default ) where T : class
123+ public static async Task ExecuteBulkInsertAsync < T > (
124+ this DbContext dbContext ,
125+ IEnumerable < T > entities ,
126+ Action < BulkInsertOptions > configure ,
127+ OnConflictOptions ? onConflict = null ,
128+ CancellationToken cancellationToken = default
129+ )
130+ where T : class
64131 {
65132 var dbSet = dbContext . Set < T > ( ) ;
66133 if ( dbSet == null )
@@ -71,6 +138,25 @@ public static async Task ExecuteBulkInsertAsync<T>(this DbContext dbContext, IEn
71138 await dbSet . ExecuteBulkInsertAsync ( entities , configure , onConflict , cancellationToken ) ;
72139 }
73140
141+ /// <summary>
142+ /// Executes a bulk insert operation without returning the inserted/updated entities, from the DbContext.
143+ /// </summary>
144+ public static async Task ExecuteBulkInsertAsync < T > (
145+ this DbContext dbContext ,
146+ IEnumerable < T > entities ,
147+ OnConflictOptions ? onConflict = null ,
148+ CancellationToken cancellationToken = default
149+ ) where T : class
150+ {
151+ var dbSet = dbContext . Set < T > ( ) ;
152+ if ( dbSet == null )
153+ {
154+ throw new InvalidOperationException ( $ "DbSet of type { typeof ( T ) . Name } not found in DbContext.") ;
155+ }
156+
157+ await dbSet . ExecuteBulkInsertAsync < T , BulkInsertOptions > ( entities , _ => { } , onConflict , cancellationToken ) ;
158+ }
159+
74160 /// <summary>
75161 /// Executes a bulk insert operation returning the inserted/updated entities, from the DbSet (synchronous variant).
76162 /// </summary>
@@ -145,14 +231,22 @@ private static DbContext GetDbContext<T>(this DbSet<T> dbSet) where T : class
145231 return ( infrastructure . Instance . GetService ( typeof ( ICurrentDbContext ) ) as ICurrentDbContext ) ! . Context ;
146232 }
147233
148- private static IBulkInsertProvider InitProvider < T > ( DbSet < T > dbSet , Action < BulkInsertOptions > ? configure , out DbContext context ,
149- out BulkInsertOptions options ) where T : class
234+ private static IBulkInsertProvider InitProvider < T , TOptions > ( DbSet < T > dbSet , Action < TOptions > ? configure , out DbContext context ,
235+ out TOptions options ) where T : class where TOptions : BulkInsertOptions
150236 {
151237 context = dbSet . GetDbContext ( ) ;
152238 var provider = context . GetService < IBulkInsertProvider > ( ) ;
153239
154- options = new BulkInsertOptions ( ) ;
240+ var defaultOptions = provider . GetDefaultOptions ( ) ;
241+
242+ if ( defaultOptions is not TOptions castedOptions )
243+ {
244+ throw new InvalidOperationException ( $ "Options type mismatch. Expected { defaultOptions . GetType ( ) . Name } , but got { typeof ( TOptions ) . Name } .") ;
245+ }
246+
247+ options = castedOptions ;
155248 configure ? . Invoke ( options ) ;
249+
156250 return provider ;
157251 }
158252}
0 commit comments