13
13
using System . Collections ;
14
14
using System . Collections . Generic ;
15
15
using System . Data ;
16
+ using System . Linq ;
16
17
using System . Text ;
17
18
using ServiceStack . Text ;
18
19
@@ -348,5 +349,123 @@ public static ulong ConvertToULong(byte[] bytes)
348
349
var ulongValue = BitConverter . ToUInt64 ( bytes , 0 ) ;
349
350
return ulongValue ;
350
351
}
352
+
353
+ public static List < Parent > Merge < Parent , Child > ( this Parent parent , List < Child > children )
354
+ {
355
+ return new List < Parent > { parent } . Merge ( children ) ;
356
+ }
357
+
358
+ public static List < Parent > Merge < Parent , Child > ( this List < Parent > parents , List < Child > children )
359
+ {
360
+ var modelDef = ModelDefinition < Parent > . Definition ;
361
+ var fieldDef = modelDef . AllFieldDefinitionsArray . FirstOrDefault (
362
+ x => ( x . FieldType == typeof ( Child ) || x . FieldType == typeof ( List < Child > ) ) && x . IsReference ) ;
363
+
364
+ if ( fieldDef == null )
365
+ throw new Exception ( "Could not find Child Reference for '{0}' on Parent '{1}'" . Fmt ( typeof ( Child ) . Name , typeof ( Parent ) . Name ) ) ;
366
+
367
+ var listInterface = fieldDef . FieldType . GetTypeWithGenericInterfaceOf ( typeof ( IList < > ) ) ;
368
+ if ( listInterface != null )
369
+ {
370
+ var refType = listInterface . GenericTypeArguments ( ) [ 0 ] ;
371
+ var refModelDef = refType . GetModelDefinition ( ) ;
372
+ var refField = modelDef . GetRefFieldDef ( refModelDef , refType ) ;
373
+
374
+ SetListChildResults ( parents , modelDef , fieldDef , refType , children , refField ) ;
375
+ }
376
+ else
377
+ {
378
+ var refType = fieldDef . FieldType ;
379
+
380
+ var refModelDef = refType . GetModelDefinition ( ) ;
381
+
382
+ var refSelf = modelDef . GetSelfRefFieldDefIfExists ( refModelDef , fieldDef ) ;
383
+ var refField = refSelf == null
384
+ ? modelDef . GetRefFieldDef ( refModelDef , refType )
385
+ : modelDef . GetRefFieldDefIfExists ( refModelDef ) ;
386
+
387
+ if ( refSelf != null )
388
+ {
389
+ SetRefSelfChildResults ( parents , fieldDef , refModelDef , refSelf , children ) ;
390
+ }
391
+ else if ( refField != null )
392
+ {
393
+ SetRefFieldChildResults ( parents , modelDef , fieldDef , refField , children ) ;
394
+ }
395
+ }
396
+
397
+ return parents ;
398
+ }
399
+
400
+ internal static void SetListChildResults < Parent > ( List < Parent > parents , ModelDefinition modelDef ,
401
+ FieldDefinition fieldDef , Type refType , IList childResults , FieldDefinition refField )
402
+ {
403
+ var map = new Dictionary < object , List < object > > ( ) ;
404
+ List < object > refValues ;
405
+
406
+ foreach ( var result in childResults )
407
+ {
408
+ var refValue = refField . GetValue ( result ) ;
409
+ if ( ! map . TryGetValue ( refValue , out refValues ) )
410
+ {
411
+ map [ refValue ] = refValues = new List < object > ( ) ;
412
+ }
413
+ refValues . Add ( result ) ;
414
+ }
415
+
416
+ var untypedApi = refType . CreateTypedApi ( ) ;
417
+ foreach ( var result in parents )
418
+ {
419
+ var pkValue = modelDef . PrimaryKey . GetValue ( result ) ;
420
+ if ( map . TryGetValue ( pkValue , out refValues ) )
421
+ {
422
+ var castResults = untypedApi . Cast ( refValues ) ;
423
+ fieldDef . SetValueFn ( result , castResults ) ;
424
+ }
425
+ }
426
+ }
427
+
428
+ internal static void SetRefSelfChildResults < Parent > ( List < Parent > parents , FieldDefinition fieldDef , ModelDefinition refModelDef , FieldDefinition refSelf , IList childResults )
429
+ {
430
+ var map = new Dictionary < object , object > ( ) ;
431
+ foreach ( var result in childResults )
432
+ {
433
+ var pkValue = refModelDef . PrimaryKey . GetValue ( result ) ;
434
+ map [ pkValue ] = result ;
435
+ }
436
+
437
+ foreach ( var result in parents )
438
+ {
439
+ object childResult ;
440
+ var fkValue = refSelf . GetValue ( result ) ;
441
+ if ( fkValue != null && map . TryGetValue ( fkValue , out childResult ) )
442
+ {
443
+ fieldDef . SetValueFn ( result , childResult ) ;
444
+ }
445
+ }
446
+ }
447
+
448
+ internal static void SetRefFieldChildResults < Parent > ( List < Parent > parents , ModelDefinition modelDef ,
449
+ FieldDefinition fieldDef , FieldDefinition refField , IList childResults )
450
+ {
451
+ var map = new Dictionary < object , object > ( ) ;
452
+
453
+ foreach ( var result in childResults )
454
+ {
455
+ var refValue = refField . GetValue ( result ) ;
456
+ map [ refValue ] = result ;
457
+ }
458
+
459
+ foreach ( var result in parents )
460
+ {
461
+ object childResult ;
462
+ var pkValue = modelDef . PrimaryKey . GetValue ( result ) ;
463
+ if ( map . TryGetValue ( pkValue , out childResult ) )
464
+ {
465
+ fieldDef . SetValueFn ( result , childResult ) ;
466
+ }
467
+ }
468
+ }
469
+
351
470
}
352
471
}
0 commit comments