@@ -259,20 +259,18 @@ public override async Task DeleteAsync(IEnumerable<TKey> keys, CancellationToken
259
259
key ,
260
260
includeVectors ) ;
261
261
262
- using SqlDataReader reader = await connection . ExecuteWithErrorHandlingAsync (
262
+ return await connection . ExecuteWithErrorHandlingAsync (
263
263
this . _collectionMetadata ,
264
264
operationName : "Get" ,
265
265
async ( ) =>
266
266
{
267
- SqlDataReader reader = await command . ExecuteReaderAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
267
+ using SqlDataReader reader = await command . ExecuteReaderAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
268
268
await reader . ReadAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
269
- return reader ;
269
+ return reader . HasRows
270
+ ? this . _mapper . MapFromStorageToDataModel ( reader , includeVectors )
271
+ : null ;
270
272
} ,
271
273
cancellationToken ) . ConfigureAwait ( false ) ;
272
-
273
- return reader . HasRows
274
- ? this . _mapper . MapFromStorageToDataModel ( new SqlDataReaderDictionary ( reader , this . _model . VectorProperties ) , includeVectors )
275
- : default ;
276
274
}
277
275
278
276
/// <inheritdoc/>
@@ -320,12 +318,22 @@ public override async IAsyncEnumerable<TRecord> GetAsync(IEnumerable<TKey> keys,
320
318
( ) => command . ExecuteReaderAsync ( cancellationToken ) ,
321
319
cancellationToken ) . ConfigureAwait ( false ) ;
322
320
323
- while ( await reader . ReadWithErrorHandlingAsync (
324
- this . _collectionMetadata ,
325
- "GetBatch" ,
326
- cancellationToken ) . ConfigureAwait ( false ) )
321
+ while ( true )
327
322
{
328
- yield return this . _mapper . MapFromStorageToDataModel ( new SqlDataReaderDictionary ( reader , this . _model . VectorProperties ) , includeVectors ) ;
323
+ TRecord ? record = await VectorStoreErrorHandler . RunOperationAsync < TRecord ? , SqlException > (
324
+ this . _collectionMetadata ,
325
+ "GetBatch" ,
326
+ async ( ) => await reader . ReadAsync ( cancellationToken ) . ConfigureAwait ( false )
327
+ ? this . _mapper . MapFromStorageToDataModel ( reader , includeVectors )
328
+ : null )
329
+ . ConfigureAwait ( false ) ;
330
+
331
+ if ( record is null )
332
+ {
333
+ break ;
334
+ }
335
+
336
+ yield return record ;
329
337
}
330
338
} while ( command . Parameters . Count == SqlServerConstants . MaxParameterCount ) ;
331
339
}
@@ -335,7 +343,7 @@ public override async Task UpsertAsync(TRecord record, CancellationToken cancell
335
343
{
336
344
Verify . NotNull ( record ) ;
337
345
338
- IReadOnlyList < Embedding > ? [ ] ? generatedEmbeddings = null ;
346
+ Dictionary < VectorPropertyModel , IReadOnlyList < Embedding > > ? generatedEmbeddings = null ;
339
347
340
348
var vectorPropertyCount = this . _model . VectorProperties . Count ;
341
349
for ( var i = 0 ; i < vectorPropertyCount ; i ++ )
@@ -354,8 +362,8 @@ public override async Task UpsertAsync(TRecord record, CancellationToken cancell
354
362
// and generate embeddings for them in a single batch. That's some more complexity though.
355
363
if ( vectorProperty . TryGenerateEmbedding < TRecord , Embedding < float > > ( record , cancellationToken , out var floatTask ) )
356
364
{
357
- generatedEmbeddings ??= new IReadOnlyList < Embedding > ? [ vectorPropertyCount ] ;
358
- generatedEmbeddings [ i ] = [ await floatTask . ConfigureAwait ( false ) ] ;
365
+ generatedEmbeddings ??= new Dictionary < VectorPropertyModel , IReadOnlyList < Embedding > > ( vectorPropertyCount ) ;
366
+ generatedEmbeddings [ vectorProperty ] = [ await floatTask . ConfigureAwait ( false ) ] ;
359
367
}
360
368
else
361
369
{
@@ -370,7 +378,8 @@ public override async Task UpsertAsync(TRecord record, CancellationToken cancell
370
378
this . _schema ,
371
379
this . Name ,
372
380
this . _model ,
373
- this . _mapper . MapFromDataToStorageModel ( record , recordIndex : 0 , generatedEmbeddings ) ) ;
381
+ record ,
382
+ generatedEmbeddings ) ;
374
383
375
384
await connection . ExecuteWithErrorHandlingAsync (
376
385
this . _collectionMetadata ,
@@ -393,7 +402,7 @@ public override async Task UpsertAsync(IEnumerable<TRecord> records, Cancellatio
393
402
IReadOnlyList < TRecord > ? recordsList = null ;
394
403
395
404
// If an embedding generator is defined, invoke it once per property for all records.
396
- IReadOnlyList < Embedding > ? [ ] ? generatedEmbeddings = null ;
405
+ Dictionary < VectorPropertyModel , IReadOnlyList < Embedding > > ? generatedEmbeddings = null ;
397
406
398
407
var vectorPropertyCount = this . _model . VectorProperties . Count ;
399
408
for ( var i = 0 ; i < vectorPropertyCount ; i ++ )
@@ -426,8 +435,8 @@ public override async Task UpsertAsync(IEnumerable<TRecord> records, Cancellatio
426
435
// and generate embeddings for them in a single batch. That's some more complexity though.
427
436
if ( vectorProperty . TryGenerateEmbeddings < TRecord , Embedding < float > > ( records , cancellationToken , out var floatTask ) )
428
437
{
429
- generatedEmbeddings ??= new IReadOnlyList < Embedding > ? [ vectorPropertyCount ] ;
430
- generatedEmbeddings [ i ] = ( IReadOnlyList < Embedding < float > > ) await floatTask . ConfigureAwait ( false ) ;
438
+ generatedEmbeddings ??= new Dictionary < VectorPropertyModel , IReadOnlyList < Embedding > > ( vectorPropertyCount ) ;
439
+ generatedEmbeddings [ vectorProperty ] = ( IReadOnlyList < Embedding < float > > ) await floatTask . ConfigureAwait ( false ) ;
431
440
}
432
441
else
433
442
{
@@ -459,9 +468,9 @@ public override async Task UpsertAsync(IEnumerable<TRecord> records, Cancellatio
459
468
this . _schema ,
460
469
this . Name ,
461
470
this . _model ,
462
- records . Skip ( taken )
463
- . Take ( SqlServerConstants . MaxParameterCount / parametersPerRecord )
464
- . Select ( ( r , i ) => this . _mapper . MapFromDataToStorageModel ( r , taken + i , generatedEmbeddings ) ) ) )
471
+ records . Skip ( taken ) . Take ( SqlServerConstants . MaxParameterCount / parametersPerRecord ) ,
472
+ firstRecordIndex : taken ,
473
+ generatedEmbeddings ) )
465
474
{
466
475
break ; // records is empty
467
476
}
@@ -613,7 +622,7 @@ private async IAsyncEnumerable<VectorSearchResult<TRecord>> ReadVectorSearchResu
613
622
}
614
623
615
624
yield return new VectorSearchResult < TRecord > (
616
- this . _mapper . MapFromStorageToDataModel ( new SqlDataReaderDictionary ( reader , vectorProperties ) , includeVectors ) ,
625
+ this . _mapper . MapFromStorageToDataModel ( reader , includeVectors ) ,
617
626
reader . GetDouble ( scoreIndex ) ) ;
618
627
}
619
628
}
@@ -655,7 +664,7 @@ public override async IAsyncEnumerable<TRecord> GetAsync(Expression<Func<TRecord
655
664
operationName : "GetAsync" ,
656
665
cancellationToken ) . ConfigureAwait ( false ) )
657
666
{
658
- yield return this . _mapper . MapFromStorageToDataModel ( new SqlDataReaderDictionary ( reader , vectorProperties ) , options . IncludeVectors ) ;
667
+ yield return this . _mapper . MapFromStorageToDataModel ( reader , options . IncludeVectors ) ;
659
668
}
660
669
}
661
670
}
0 commit comments