-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprint.html
1881 lines (1776 loc) · 146 KB
/
print.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML>
<html lang="en" class="light" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Buzruk.GenericRepository</title>
<meta name="robots" content="noindex">
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body class="sidebar-visible no-js">
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('light')
html.classList.add(theme);
var body = document.querySelector('body');
body.classList.remove('no-js')
body.classList.add('js');
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var body = document.querySelector('body');
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
body.classList.remove('sidebar-visible');
body.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="Home.html"><strong aria-hidden="true">1.</strong> Welcome Aboard!</a></li><li class="chapter-item expanded "><a href="Installation.html"><strong aria-hidden="true">2.</strong> Installation Blastoff!</a></li><li class="chapter-item expanded affix "><li class="part-title">⚡️ Core Functionalities</li><li class="chapter-item expanded "><a href="Usage-examples.html"><strong aria-hidden="true">3.</strong> Code Examples Galore!</a></li><li class="chapter-item expanded "><div><strong aria-hidden="true">4.</strong> CRUD</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="GetAsync-and-Get.html"><strong aria-hidden="true">4.1.</strong> GetAsync & Get</a></li><li class="chapter-item expanded "><a href="GetPagedAsync-and-GetPaged.html"><strong aria-hidden="true">4.2.</strong> GetPagedAsync & GetPaged</a></li><li class="chapter-item expanded "><a href="AddAsync-and-Add.html"><strong aria-hidden="true">4.3.</strong> AddAsync & Add</a></li><li class="chapter-item expanded "><a href="AddRangeAsync-and-AddRange.html"><strong aria-hidden="true">4.4.</strong> AddRangeAsync & AddRange</a></li><li class="chapter-item expanded "><a href="UpdateAsync-and-Update.html"><strong aria-hidden="true">4.5.</strong> UpdateAsync & Update</a></li><li class="chapter-item expanded "><a href="updateRangeAsync-and-UpdateRange.html"><strong aria-hidden="true">4.6.</strong> UpdateRangeAsync & UpdateRange</a></li><li class="chapter-item expanded "><a href="RemoveAsync-and-Remove.html"><strong aria-hidden="true">4.7.</strong> RemoveAsync & Remove</a></li><li class="chapter-item expanded "><a href="RemoveRangeAsync-and-RemoveRange.html"><strong aria-hidden="true">4.8.</strong> RemoveRangeAsync & RemoveRange</a></li></ol></li><li class="chapter-item expanded "><div><strong aria-hidden="true">5.</strong> Other Methods</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="ExistsAsync-and-Exists.html"><strong aria-hidden="true">5.1.</strong> ExistsAsync & Exists</a></li><li class="chapter-item expanded "><a href="CountAsync-and-Count.html"><strong aria-hidden="true">5.2.</strong> CountAsync & Count</a></li><li class="chapter-item expanded "><a href="LongCountAsync-and-LongCount.html"><strong aria-hidden="true">5.3.</strong> LongCountAsync & LongCount</a></li><li class="chapter-item expanded "><a href="CountByAsync-and-CountBy.html"><strong aria-hidden="true">5.4.</strong> CountByAsync & CountBy</a></li><li class="chapter-item expanded "><a href="saveChangesAsync-and-SaveChanges.html"><strong aria-hidden="true">5.5.</strong> SaveChangesAsync & SaveChanges</a></li></ol></li><li class="chapter-item expanded "><li class="part-title">Support & Community</li><li class="chapter-item expanded "><a href="Faq.html"><strong aria-hidden="true">6.</strong> FAQ: Your Questions Answered</a></li><li class="chapter-item expanded "><a href="Troubleshooting.html"><strong aria-hidden="true">7.</strong> Troubleshooting Like a Pro</a></li><li class="chapter-item expanded "><a href="CONTRIBUTING.html"><strong aria-hidden="true">8.</strong> Contribute & Make an Impact!</a></li><li class="chapter-item expanded affix "><li class="part-title">Additional Resources</li><li class="chapter-item expanded "><a href="CHANGELOG.html"><strong aria-hidden="true">9.</strong> CHANGELOG.md: Stay Updated</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<!-- Track and set sidebar scroll position -->
<script>
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
sidebarScrollbox.addEventListener('click', function(e) {
if (e.target.tagName === 'A') {
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
}
}, { passive: true });
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
sessionStorage.removeItem('sidebar-scroll');
if (sidebarScrollTop) {
// preserve sidebar scroll position when navigating via links within sidebar
sidebarScrollbox.scrollTop = sidebarScrollTop;
} else {
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
var activeSection = document.querySelector('#sidebar .active');
if (activeSection) {
activeSection.scrollIntoView({ block: 'center' });
}
}
</script>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Buzruk.GenericRepository</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="welcome-aboard-buzrukgenericrepository-level-up-your-net-data-access"><a class="header" href="#welcome-aboard-buzrukgenericrepository-level-up-your-net-data-access">Welcome Aboard! Buzruk.GenericRepository: Level Up Your .NET Data Access</a></h1>
<p><strong>Tired of writing boilerplate code for CRUD operations? Welcome to the future of data access in .NET!</strong> Buzruk.GenericRepository is your <strong>supercharged</strong>, <strong>asynchronous-first</strong> generic repository, designed to <strong>revolutionize</strong> the way you interact with your data.</p>
<p><strong>This modern powerhouse</strong> provides a <strong>unified interface</strong> to work with various entities, allowing you to <strong>focus on building amazing features</strong> while it handles the data interaction heavy lifting. Here's what awaits you:</p>
<h2 id="-asynchronous-excellence"><a class="header" href="#-asynchronous-excellence">⚡️ Asynchronous Excellence</a></h2>
<ul>
<li>Ditch the wait! Embrace the power of <strong>asynchronous methods by default</strong> for <strong>non-blocking, efficient data retrieval and manipulation</strong>. Free your UI threads and keep your applications responsive!</li>
<li><strong>Synchronous Options</strong>: Still need compatibility with legacy code or specific use cases? We've got you covered with included synchronous counterparts.</li>
</ul>
<h2 id="effortless-crud-operations"><a class="header" href="#effortless-crud-operations">Effortless CRUD Operations</a></h2>
<ul>
<li><strong>Intuitive Methods</strong>: Perform essential Create, Read, Update, and Delete (CRUD) actions with ease using methods like <code>GetAsync</code>, <code>GetPagedAsync</code>, <code>AddAsync</code>, <code>AddRangeAsync</code>, <code>UpdateAsync</code>, and more. Simplify complex data management and write cleaner code.</li>
<li><strong>Flexible Data Fetching</strong>: Find specific entities by ID or filter them based on your criteria using the versatile GetAsync method. <strong>Get exactly the data you need, when you need it</strong>.</li>
</ul>
<h2 id="handle-large-datasets-with-grace"><a class="header" href="#handle-large-datasets-with-grace">Handle Large Datasets with Grace</a></h2>
<ul>
<li><strong>Paged Data Fetching (Async)</strong>: Say goodbye to overwhelming data loads! Retrieve data in manageable chunks with <code>GetPagedAsync</code>. This is ideal for pagination and performance optimization in applications dealing with large datasets.</li>
<li><strong>Efficient Counting</strong>: Gain a clear picture of your data with <code>CountAsync</code> for total entity counts or utilize <code>LongCountAsync</code> for accurate counts even with massive datasets.</li>
</ul>
<h2 id="more-power-at-your-fingertips"><a class="header" href="#more-power-at-your-fingertips">More Power at Your Fingertips</a></h2>
<ul>
<li><strong>Targeted Counting (Async)</strong>: Delve deeper with <code>CountByAsync</code>. Asynchronously count entities based on specific conditions, empowering you with granular insights into your data distribution.</li>
<li><strong>Bulk Operations (Async)</strong>: Optimize performance with <code>AddRangeAsync</code> and <code>UpdateRangeAsync</code> methods, allowing you to add or update multiple entities efficiently in a single operation.</li>
</ul>
<h2 id="built-for-seamless-integration"><a class="header" href="#built-for-seamless-integration">Built for Seamless Integration</a></h2>
<ul>
<li><strong>Effortless Integration with Entity Framework Core</strong>: Designed to work seamlessly with Entity Framework Core, allowing you to leverage its powerful features without additional configuration.</li>
</ul>
<h2 id="optional-advanced-features"><a class="header" href="#optional-advanced-features">Optional Advanced Features</a></h2>
<ul>
<li><strong>Eager Loading (Optional)</strong>: Boost performance by pre-fetching related entities when retrieving primary data (including an asynchronous <code>EagerLoadAsync</code> option), minimizing subsequent database calls.</li>
<li><strong>Change Tracking (Optional)</strong>: Track entity modifications for efficient saving updates (requires configuration).</li>
</ul>
<h2 id="a-collaborative-future"><a class="header" href="#a-collaborative-future">A Collaborative Future</a></h2>
<ul>
<li>We actively encourage contributions to broaden support for additional data access providers beyond Entity Framework Core! Let's make this a universally applicable solution!</li>
<li>Our relentless pursuit of unit testing coverage ensures unmatched reliability. You can trust your data access layer with confidence!</li>
<li>Expect even more detailed examples, tutorials, and guides to transform you into a data access master (coming soon)!</li>
</ul>
<h2 id="ready-to-experience-the-modern-data-access-revolution"><a class="header" href="#ready-to-experience-the-modern-data-access-revolution">Ready to Experience the Modern Data Access Revolution?</a></h2>
<p>Get started with Buzruk.GenericRepository today and unlock a whole new level of efficiency and performance in your .NET data access! Dive deeper into the following sections to explore installation, usage examples, and the full API reference:</p>
<ul>
<li><strong>Installation</strong>: Effortlessly integrate the package into your project.</li>
<li><strong>Usage Examples</strong>: Practical code snippets to guide you through common operations.</li>
<li><strong>API Reference</strong>: Comprehensive documentation for every class and method.</li>
</ul>
<p><strong>Join the community and start building amazing things!</strong></p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="installation-blastoff---integrate-your-package-name-in-a-flash"><a class="header" href="#installation-blastoff---integrate-your-package-name-in-a-flash">Installation Blastoff! - Integrate [Your Package Name] in a Flash</a></h1>
<p>Get ready to <strong>launch your data access game into the stratosphere</strong> with [Your Package Name]! Integrating this powerhouse package into your .NET project is a <strong>one-click</strong> (well, one-command) operation. Here's how to seamlessly inject its functionalities into your project:</p>
<ol>
<li>Open Your Command Prompt (or Terminal) - Your Mission Control</li>
</ol>
<p>First things first, navigate to your project directory using your preferred terminal or command prompt. This is your mission control center where you'll initiate the installation sequence.</p>
<ol start="2">
<li>Unleash the Power of NuGet - Your Launch System</li>
</ol>
<p>NuGet, the .NET package manager, is your rocket fuel for this installation. Fire up the command prompt and type in this powerful command:</p>
<pre><code class="language-bash">dotnet add package [YourPackageName]
</code></pre>
<ol start="3">
<li>Hit Enter and Blast Off!</li>
</ol>
<p>Press Enter, and boom! NuGet takes care of the rest, downloading and installing the package seamlessly within your project. Congratulations, you've successfully integrated [Your Package Name] and are now ready to leverage its modern data access magic!</p>
<h2 id="additional-tips-for-a-smooth-landing"><a class="header" href="#additional-tips-for-a-smooth-landing">Additional Tips for a Smooth Landing</a></h2>
<ul>
<li><strong>Ensure a Stable Internet Connection</strong>: For a smooth installation, make sure you have a stable internet connection to allow NuGet to download the package.</li>
<li><strong>Double-Check the Package Name</strong>: Pay close attention to the spelling of your package name in the command to avoid any installation errors.</li>
</ul>
<h2 id="ready-to-take-flight-with-enhanced-data-access"><a class="header" href="#ready-to-take-flight-with-enhanced-data-access">Ready to Take Flight with Enhanced Data Access?</a></h2>
<p>With [Your Package Name] on board, you're equipped with a state-of-the-art, asynchronous-first data access solution. Get ready to <strong>streamline your data interaction</strong>, focus on building incredible features, and leave the heavy lifting to this powerful repository! The sky's the limit for your .NET applications!</p>
<p><strong>Now that you've installed the package, explore the next sections to</strong>:</p>
<ul>
<li><strong>Reference the Namespace</strong>: Unlock the repository's functionalities within your code.</li>
<li><strong>Create an Instance</strong>: Activate your data access superpowers!</li>
<li><strong>Explore the Power (Optional)</strong>: Dive deeper into code examples and API reference.</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h1 id="code-examples-galore-unleash-the-power-of-buzrukgenericrepository"><a class="header" href="#code-examples-galore-unleash-the-power-of-buzrukgenericrepository">Code Examples Galore! Unleash the Power of Buzruk.GenericRepository</a></h1>
<p>This section equips you with practical code snippets showcasing the core functionalities of Buzruk.GenericRepository. Dive into these examples and explore dedicated Wiki pages for each method, providing a comprehensive breakdown of usage and best practices.</p>
<h2 id="crud-operations-effortless-data-management"><a class="header" href="#crud-operations-effortless-data-management">CRUD Operations: Effortless Data Management</a></h2>
<ol>
<li>Retrieving Entities:
<ul>
<li><strong>Get (Synchronous)</strong>: Grab a specific entity by ID with lightning speed. (Link to Wiki page for Get)</li>
<li><strong>GetAsync (Asynchronous)</strong>: Fetch an entity asynchronously for a smooth and responsive user experience. (Link to Wiki page for GetAsync)</li>
<li><strong>GetPagedAsync (Asynchronous)</strong>: Conquer large datasets by retrieving data in manageable chunks, ideal for pagination. (Link to Wiki page for GetPagedAsync)</li>
</ul>
</li>
<li>Creating Entities:
<ul>
<li><strong>Add (Synchronous)</strong>: Effortlessly create a new entity and add it to your data store. (Link to Wiki page for Add)</li>
<li><strong>AddAsync (Asynchronous)</strong>: Asynchronously add a new entity, keeping your UI responsive. (Link to Wiki page for AddAsync)</li>
</ul>
</li>
<li>Updating Entities:
<ul>
<li><strong>Update (Synchronous)</strong>: Modify an existing entity's properties and persist the changes. (Link to Wiki page for Update)</li>
<li><strong>UpdateAsync (Asynchronous)</strong>: Asynchronously update an entity, ensuring a smooth user experience. (Link to Wiki page for UpdateAsync)</li>
</ul>
</li>
<li>Deleting Entities:
<ul>
<li><strong>Remove (Synchronous)</strong>: Remove an entity from the data store efficiently. (Link to Wiki page for Remove)</li>
<li><strong>RemoveAsync (Asynchronous)</strong>: Asynchronously delete an entity, maintaining responsiveness. (Link to Wiki page for RemoveAsync)</li>
</ul>
</li>
</ol>
<h2 id="bulk-operations-efficiency-at-your-fingertips"><a class="header" href="#bulk-operations-efficiency-at-your-fingertips">Bulk Operations: Efficiency at Your Fingertips</a></h2>
<ul>
<li><strong>AddRangeAsync (Asynchronous)</strong>: Add multiple entities in a single asynchronous operation, optimizing performance for large datasets. (Link to Wiki page for AddRangeAsync)</li>
<li><strong>UpdateRangeAsync (Asynchronous)</strong>: Update multiple entities asynchronously, streamlining bulk modifications. (Link to Wiki page for UpdateRangeAsync)</li>
</ul>
<h2 id="data-insights--utility-methods"><a class="header" href="#data-insights--utility-methods">Data Insights & Utility Methods</a></h2>
<ul>
<li><strong>Exists (Synchronous)</strong>: Swiftly check if an entity exists based on its ID. (Link to Wiki page for Exists)</li>
<li><strong>ExistsAsync (Asynchronou)</strong>: Asynchronously determine if an entity exists. (Link to Wiki page for ExistsAsync)</li>
<li><strong>Count (Synchronous)</strong>: Get the total number of entities in your data store. (Link to Wiki page for Count)</li>
<li><strong>CountAsync (Asynchronous)</strong>: Asynchronously retrieve the total entity count. (Link to Wiki page for CountAsync)</li>
<li><strong>LongCount (Synchronous)</strong>: Accurately count entities, even with massive datasets. (Link to Wiki page for LongCount)</li>
<li><strong>LongCountAsync (Asynchronous)</strong>: Asynchronously count a large number of entities. (Link to Wiki page for LongCountAsync)</li>
<li><strong>CountBy (Synchronous)</strong>: Count entities based on specific criteria for granular data insights. (Link to Wiki page for CountBy)</li>
<li><strong>CountByAsync (Asynchronous)</strong>: Asynchronously count entities based on conditions. (Link to Wiki page for CountByAsync)</li>
</ul>
<h2 id="optional-advanced-features-1"><a class="header" href="#optional-advanced-features-1">Optional Advanced Features</a></h2>
<ul>
<li><strong>Eager Loading (Optional)</strong>: Boost performance by pre-fetching related entities when retrieving primary data (including an asynchronous EagerLoadAsync option). (Link to Wiki page for Eager Loading - if applicable)</li>
<li><strong>Change Tracking (Optional)</strong>: Track entity modifications for efficient saving updates (requires configuration). (Link to Wiki page for Change Tracking - if applicable)</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h1 id="getasync--get-power-up-your-data-retrieval-in-buzrukgenericrepository"><a class="header" href="#getasync--get-power-up-your-data-retrieval-in-buzrukgenericrepository">GetAsync & Get: Power Up Your Data Retrieval in Buzruk.GenericRepository</a></h1>
<p>This section dives deep into the <code>GetAsync</code> and <code>Get</code> methods, your weapons of choice for retrieving entities in Buzruk.GenericRepository. We'll explore their functionalities, usage scenarios, comparisons, and best practices to empower you with efficient data access.</p>
<p>This comprehensive guide empowers you to master the GetAsync and Get methods within Buzruk.GenericRepository. We'll delve into their functionalities, explore various usage scenarios with different parameters, and provide examples to illustrate their power.</p>
<h2 id="unveiling-the-power-of-getasync-asynchronous"><a class="header" href="#unveiling-the-power-of-getasync-asynchronous">Unveiling the Power of <code>GetAsync</code> (Asynchronous):</a></h2>
<ul>
<li><strong>Champion of Responsiveness</strong>: <code>GetAsync</code> shines in asynchronous operations. It retrieves an entity by its ID without blocking the UI thread, keeping your applications responsive and snappy. This is particularly valuable for user interfaces where you want to avoid freezing while data is fetched.</li>
</ul>
<h3 id="example-asynchronously-retrieving-a-product"><a class="header" href="#example-asynchronously-retrieving-a-product">Example: Asynchronously Retrieving a Product</a></h3>
<pre><code class="language-csharp">// Assuming you have an instance of the repository (`repository`)
// and a product ID (`123`)
Task<Product> productTask = repository.GetAsync<Product>(123);
// Use await to get the actual product object
Product product = await productTask;
if (product != null)
{
Console.WriteLine($"Product Name: {product.Name}");
}
else
{
Console.WriteLine("Product not found.");
}
</code></pre>
<h3 id="getasync-in-action"><a class="header" href="#getasync-in-action"><code>GetAsync</code> in Action:</a></h3>
<ul>
<li>Ideal for scenarios where immediate data access isn't crucial, but maintaining a responsive UI is essential.</li>
<li>Applications with user interactions that could be interrupted by synchronous data retrieval benefit greatly from <code>GetAsync</code>.</li>
</ul>
<h2 id="understanding-get-synchronous"><a class="header" href="#understanding-get-synchronous">Understanding <code>Get</code> (Synchronous):</a></h2>
<ul>
<li><strong>Speedy Retrieval</strong>: <code>Get</code> excels in synchronous data retrieval. It fetches an entity by its ID in a single operation, making it a good choice when you need the data immediately and UI responsiveness isn't a major concern.</li>
</ul>
<h3 id="example-synchronously-retrieving-a-product"><a class="header" href="#example-synchronously-retrieving-a-product">Example: Synchronously Retrieving a Product</a></h3>
<pre><code class="language-csharp">// Assuming you have an instance of the repository (`repository`)
// and a product ID (`123`)
Product product = repository.Get<Product>(123);
if (product != null)
{
Console.WriteLine($"Product Name: {product.Name}");
}
else
{
Console.WriteLine("Product not found.");
}
</code></pre>
<h3 id="get-on-the-battlefield"><a class="header" href="#get-on-the-battlefield"><code>Get</code> on the Battlefield</a></h3>
<ul>
<li>Perfect for background tasks or processes where responsiveness isn't a priority.</li>
<li>If you need the data immediately for further processing or decision-making within the same code block, <code>Get</code> might be a suitable choice.</li>
</ul>
<h2 id="choosing-your-champion-getasync-vs-get"><a class="header" href="#choosing-your-champion-getasync-vs-get">Choosing Your Champion: <code>GetAsync</code> vs. <code>Get</code></a></h2>
<p>Here's a quick comparison to help you decide:</p>
<div class="table-wrapper"><table><thead><tr><th>Feature</th><th>GetAsync</th><th>Get</th></tr></thead><tbody>
<tr><td>Execution</td><td>Asynchronous</td><td>Synchronous</td></tr>
<tr><td>UI Responsiveness</td><td>Maintains responsiveness</td><td>Might block the UI thread</td></tr>
<tr><td>Use Cases</td><td>User interactions, background processes</td><td>Background tasks, immediate data processing</td></tr>
<tr><td>Performance (Network)</td><td>Potentially better for high latency networks</td><td>Might be slightly faster on local networks</td></tr>
</tbody></table>
</div>
<h2 id="pro-tips-for-effective-usage"><a class="header" href="#pro-tips-for-effective-usage">Pro Tips for Effective Usage</a></h2>
<ul>
<li><strong>Embrace Asynchronous Operations</strong>: In most modern applications, <code>GetAsync</code> is the recommended approach due to its responsiveness benefits.</li>
<li><strong>Consider UI Impact</strong>: If user interaction might be affected by a data retrieval block, prioritize <code>GetAsync</code>.</li>
<li><strong>Network Latency Matters</strong>: In high-latency network environments, <code>GetAsync</code> can outperform <code>Get</code> due to its non-blocking nature.</li>
<li><strong>Error Handling</strong>: Implement proper error handling mechanisms to gracefully handle cases where the entity might not be found.</li>
</ul>
<p><strong>Remember</strong>: Both GetAsync and Get offer valuable functionalities for retrieving entities. By understanding their strengths, weaknesses, and use cases, you can make informed decisions to optimize your data access strategy in Buzruk.GenericRepository.</p>
<h2 id="understanding-getasync-asynchronous-and-get-synchronous"><a class="header" href="#understanding-getasync-asynchronous-and-get-synchronous">Understanding <code>GetAsync</code> (Asynchronous) and <code>Get</code> (Synchronous)</a></h2>
<ul>
<li><strong>Core Functionality</strong>: Both methods serve the same purpose: retrieving an entity by its ID.
<ul>
<li><code>GetAsync</code> operates asynchronously, excelling in responsiveness for UI-centric applications.</li>
<li><code>Get</code> works synchronously, fetching data in a single operation, making it suitable for background tasks.</li>
</ul>
</li>
</ul>
<h3 id="exploring-the-powerhouse-parameters"><a class="header" href="#exploring-the-powerhouse-parameters">Exploring the Powerhouse Parameters</a></h3>
<p>Both methods offer a plethora of optional parameters that significantly enhance data retrieval capabilities. Here's a breakdown of the key ones:</p>
<ol>
<li>Predicates (Expression<Func<T, bool>>):
<ul>
<li><strong>Function</strong>: Filter entities based on specific criteria.</li>
<li><strong>Usage</strong>: Pass a lambda expression that evaluates to <code>true</code> for entities you want to retrieve.</li>
</ul>
</li>
</ol>
<p><strong>Example: Get Products with Price Greater Than $100 (Async):</strong></p>
<pre><code class="language-csharp">Task<Product> productTask = repository.GetAsync<Product>(
predicate: p => p.Price > 100
);
// Await the task to get the product
Product product = await productTask;
</code></pre>
<ol start="2">
<li><code>orderBy</code> (Expression<Func<T, object>>) and <code>thenBy</code> (Expression<Func<T, object>>):
<ul>
<li><strong>Function</strong>: Order retrieved entities based on one or more properties.</li>
<li><strong>Usage</strong>: Pass a lambda expression specifying the property for sorting (ascending order by default). Use <code>thenBy</code> for chained sorting (optional).</li>
</ul>
</li>
</ol>
<p><strong>Example: Get Top 3 Products Ordered by Price (Descending) with <code>thenBy</code> for Name (Async):</strong></p>
<pre><code class="language-csharp">Task<List<Product>> productsTask = repository.GetAsync<Product>(
orderBy: p => p.Price descending,
thenBy: p => p.Name
).Take(3); // Limit to top 3 products
List<Product> products = await productsTask;
foreach (var product in products)
{
Console.WriteLine($"Product: {product.Name}, Price: ${product.Price}");
}
</code></pre>
<ol start="3">
<li><code>includes</code> (Expression<Func<T, object>>[]) and <code>thenInclude</code> (Expression<Func<T, object>>[]):
<ul>
<li><strong>Function</strong>: Eagerly load related entities along with the primary entity.</li>
<li><strong>Usage</strong>: Pass an array of lambda expressions specifying the navigation properties to include. Use <code>thenInclude</code> for nested eager loading (optional).</li>
</ul>
</li>
</ol>
<p><strong>Example: Get Product with its Category (Async):</strong></p>
<pre><code class="language-csharp">Task<Product> productTask = repository.GetAsync<Product>(
includes: p => p.Category
);
Product product = await productTask;
if (product != null)
{
Console.WriteLine($"Product Name: {product.Name}");
Console.WriteLine($"Category Name: {product.Category.Name}");
}
</code></pre>
<ol start="4">
<li><code>tracking</code> (bool):
<ul>
<li><strong>Function</strong>: Controls whether to track entity changes for potential updates (optional, might require repository configuration for <code>UpdateAsync</code> to work).</li>
<li><strong>Usage</strong>: Set to <code>true</code> to enable change tracking.</li>
</ul>
</li>
</ol>
<p><strong>Important Note</strong>: Refer to your repository's specific documentation for any additional parameters or configuration requirements related to change tracking.</p>
<h3 id="behavior-without-parameters"><a class="header" href="#behavior-without-parameters">Behavior Without Parameters</a></h3>
<ul>
<li>If no parameters are provided, both <code>GetAsync</code> and <code>Get</code> retrieve the entity by its ID only.</li>
<li>The returned value is a <code>Product</code> object (or your specific entity type) if the entity is found, or <code>null</code> if not found.</li>
</ul>
<h3 id="remember"><a class="header" href="#remember">Remember</a></h3>
<ul>
<li>Prioritize <code>GetAsync</code> for responsive UI-centric applications.</li>
<li>Choose Get for background tasks or scenarios where immediate data access is critical.</li>
<li>Leverage predicates for filtering, <code>orderBy</code>/<code>thenBy</code> for sorting, <code>includes</code>/<code>thenInclude</code> for eager loading, and <code>tracking</code> (if supported) for efficient updates.</li>
<li>Always refer to your repository's documentation for complete parameter details and configuration requirements.</li>
</ul>
<p>By mastering these advanced functionalities, you can unlock the full potential of <code>GetAsync</code> and <code>Get</code>, enabling you to retrieve and manipulate data with precision and efficiency within Buzruk.GenericRepository.</p>
<div style="break-before: page; page-break-before: always;"></div><h1 id="getpagedasync--getpaged-mastering-pagination-in-buzrukgenericrepository"><a class="header" href="#getpagedasync--getpaged-mastering-pagination-in-buzrukgenericrepository">GetPagedAsync & GetPaged: Mastering Pagination in Buzruk.GenericRepository</a></h1>
<p>This in-depth guide equips you to conquer large datasets effectively using <code>GetPagedAsync</code> and <code>GetPaged</code> methods within Buzruk.GenericRepository. We'll explore their functionalities, delve into various parameters for customized pagination, and provide illustrative examples to solidify your understanding.</p>
<h2 id="understanding-getpagedasync-asynchronous-and-getpaged-synchronous"><a class="header" href="#understanding-getpagedasync-asynchronous-and-getpaged-synchronous">Understanding GetPagedAsync (Asynchronous) and GetPaged (Synchronous)</a></h2>
<ul>
<li><strong>Core Purpose</strong>: Both methods retrieve data in manageable chunks, ideal for pagination and handling large datasets efficiently.
<ul>
<li><code>GetPagedAsync</code> operates asynchronously, maintaining UI responsiveness.</li>
<li><code>Get</code> works synchronously, fetching a page of data in a single operation.</li>
</ul>
</li>
</ul>
<h2 id="unveiling-the-powerhouse-parameters"><a class="header" href="#unveiling-the-powerhouse-parameters">Unveiling the Powerhouse Parameters</a></h2>
<p>Both methods offer a plethora of optional parameters that empower you to tailor pagination to your specific needs. Here's a breakdown of the key ones:</p>
<ol>
<li>Predicates (Expression<Func<T, bool>>):
<ul>
<li><strong>Function</strong>: Filter entities based on specific criteria before pagination.</li>
<li><strong>Usage</strong>: Pass a lambda expression that evaluates to <code>true</code> for entities you want to include in the results.</li>
</ul>
</li>
</ol>
<h3 id="example-getpaged-async-products-with-price-greater-than-100-page-2-size-10"><a class="header" href="#example-getpaged-async-products-with-price-greater-than-100-page-2-size-10">Example: GetPaged Async: Products with Price Greater Than $100 (Page 2, Size 10)</a></h3>
<pre><code class="language-csharp">Task<PagedResult<Product>> pagedProductsTask = repository.GetPagedAsync<Product>(
predicate: p => p.Price > 100,
pageNumber: 2,
pageSize: 10
);
PagedResult<Product> pagedProducts = await pagedProductsTask;
// Access total items and current page's items
int totalItems = pagedProducts.TotalCount;
List<Product> products = pagedProducts.Items;
Console.WriteLine($"Total Products: {totalItems}");
Console.WriteLine($"Products on Page {pageNumber}:");
foreach (var product in products)
{
Console.WriteLine($"- {product.Name}");
}
</code></pre>
<ol start="2">
<li><code>orderBy</code> (Expression<Func<T, object>>) and <code>thenBy</code> (Expression<Func<T, object>>):
<ul>
<li><strong>Function</strong>: Order retrieved entities within a page based on one or more properties.</li>
<li><strong>Usage</strong>: Pass a lambda expression specifying the property for sorting (ascending order by default). Use <code>thenBy</code> for chained sorting (optional).</li>
</ul>
</li>
</ol>
<h3 id="example-getpaged-synchronous-top-3-products-on-each-page-ordered-by-price-descending-with-thenby-for-name"><a class="header" href="#example-getpaged-synchronous-top-3-products-on-each-page-ordered-by-price-descending-with-thenby-for-name">Example: GetPaged (Synchronous): Top 3 Products on Each Page, Ordered by Price (Descending) with <code>thenBy</code> for Name</a></h3>
<pre><code class="language-csharp">var pagedProducts = repository.GetPaged<Product>(
orderBy: p => p.Price descending,
thenBy: p => p.Name,
pageNumber: 1,
pageSize: 3
).ToList(); // Convert to List for easy iteration
foreach (var product in pagedProducts)
{
Console.WriteLine($"Product Name: {product.Name}, Price: ${product.Price}");
}
</code></pre>
<ol start="3">
<li><code>includes</code> (Expression<Func<T, object>>[]) and <code>thenInclude</code> (Expression<Func<T, object>>[]):
<ul>
<li><strong>Function</strong>: Eagerly load related entities along with the primary entities within a page.</li>
<li><strong>Usage</strong>: Pass an array of lambda expressions specifying the navigation properties to include. Use <code>thenInclude</code> for nested eager loading (optional).</li>
</ul>
</li>
</ol>
<h3 id="example-getpagedasync-get-products-with-their-categories-on-page-1-size-5"><a class="header" href="#example-getpagedasync-get-products-with-their-categories-on-page-1-size-5">Example: GetPagedAsync: Get Products with their Categories on Page 1 (Size 5)</a></h3>
<pre><code class="language-csharp">Task<PagedResult<Product>> pagedProductsTask = repository.GetPagedAsync<Product>(
includes: p => p.Category,
pageNumber: 1,
pageSize: 5
);
PagedResult<Product> pagedProducts = await pagedProductsTask;
foreach (var product in pagedProducts.Items)
{
Console.WriteLine($"Product Name: {product.Name}");
Console.WriteLine($"Category Name: {product.Category.Name}");
}
</code></pre>
<ol start="4">
<li><code>tracking</code> (bool):
<ul>
<li><strong>Function</strong>: Controls whether to track entity changes for potential updates (optional, might require repository configuration for <code>UpdateAsync</code> to work).</li>
<li><strong>Usage</strong>: Set to <code>true</code> to enable change tracking within the retrieved page.</li>
</ul>
</li>
</ol>
<p><strong>Important Note</strong>: Refer to your repository's specific documentation for any additional parameters or configuration requirements related to change tracking.</p>
<h2 id="behavior-without-parameters-1"><a class="header" href="#behavior-without-parameters-1">Behavior Without Parameters</a></h2>
<ul>
<li>If no parameters are provided, both <code>GetPagedAsync</code> and <code>GetPaged</code> retrieve the first page (usually page number 1) with a default page size (often configurable).</li>
<li>The returned value is a <code>PagedResult<T></code> object (where <code>T</code> is your entity type). This object contains two key properties:</li>
</ul>
<h2 id="absolutely-heres-a-breakdown-of-the-extension-methods-provided-in-the-pagedresultsextension-class"><a class="header" href="#absolutely-heres-a-breakdown-of-the-extension-methods-provided-in-the-pagedresultsextension-class">Absolutely! Here's a breakdown of the extension methods provided in the <code>PagedResultsExtension</code> class</a></h2>
<ol>
<li>
<p><code>GetPage<T>(this PagedResults<T> pagedResults)</code></p>
<ul>
<li><strong>Functionality</strong>: This method extracts a specific page of data from the <code>PagedResults<T></code> object.</li>
<li><strong>Parameters</strong>:
<ul>
<li><strong>pagedResults</strong>: The <code>PagedResults<T></code> object containing the paginated data.</li>
</ul>
</li>
<li><strong>Returns</strong>: An <code>IEnumerable<T></code> containing the items for the requested page.</li>
<li><strong>Exception</strong>: Throws an <code>ArgumentOutOfRangeException</code> if the requested page number is outside the valid range (1 to <code>PageCount</code>).</li>
<li><strong>Usage</strong>:</li>
</ul>
<pre><code class="language-csharp">// Assuming you have a PagedResults<Product> object named 'pagedProducts'
IEnumerable<Product> currentPageProducts = pagedProducts.GetPage<Product>();
// Iterate through the products on the current page
foreach (var product in currentPageProducts)
{
Console.WriteLine($"Product Name: {product.Name}");
}
</code></pre>
</li>
<li>
<p><code>GetPartialView<T>(this PagedResults<T> model, string controllerName, string actionName, string areaName = "", string routeParameterName = "pageNumber")</code></p>
<ul>
<li><strong>Functionality</strong>: This method generates a partial view containing HTML code for page navigation based on the provided PagedResults<T> model. It leverages Razor syntax (@ symbol) for building the HTML structure.</li>
<li><strong>Parameters</strong>:
<ul>
<li><strong>model</strong>: The PagedResults<T> instance containing paging information and data.</li>
<li><strong>controllerName</strong>: The name of the controller that handles pagination requests.</li>
<li><strong>actionName</strong>: The name of the action method that handles pagination requests.</li>
<li><strong>areaName (Optional)</strong>: The name of the area for routing (defaults to empty string).</li>
<li><strong>routeParameterName (Optional)</strong>: The name of the route parameter used for the current page number (defaults to "pageNumber").</li>
</ul>
</li>
<li><strong>Returns</strong>: A string containing the generated HTML partial view for pagination.</li>
<li><strong>Notes</strong>:
<ul>
<li>This method currently uses a <code>StringBuilder</code> to construct the HTML dynamically.</li>
<li>It includes placeholder comments for functionalities like adding dark mode/light mode options (TODO).</li>
<li>The logic for generating the pagination links considers various scenarios based on the total number of pages and the current page number.</li>
<li>It also includes some basic JavaScript code to dynamically set the active page class and handle relative URLs.</li>
<li><strong>Usage</strong>:</li>
</ul>
</li>
</ul>
</li>
</ol>
<pre><code class="language-csharp">// Assuming you have a PagedResults<Product> object named 'pagedProducts'
// and your controller and action names are set
string paginationHtml = pagedProducts.GetPartialView<Product>(
controllerName: "Products",
actionName: "Index"
);
// Use the generated HTML in your Razor view
@Html.Raw(paginationHtml)
</code></pre>
<h2 id="remember-1"><a class="header" href="#remember-1">Remember:</a></h2>
<ul>
<li>The <code>GetPage</code> method is useful for retrieving a specific page of data for further processing within your application logic.</li>
<li>The <code>GetPartialView</code> method helps in creating a user-friendly pagination interface for navigating through large datasets in your web application.</li>
<li>Consider customizing the provided JavaScript code to fit your specific requirements and styling preferences.</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h2 id="understanding-addasync-asynchronous-and-add-synchronous"><a class="header" href="#understanding-addasync-asynchronous-and-add-synchronous">Understanding <code>AddAsync</code> (Asynchronous) and <code>Add</code> (Synchronous)</a></h2>
<ul>
<li><strong>Core Purpose</strong>: Both methods serve the same mission: adding a new entity to a persistence layer (often a database) managed by your Object-Relational Mapper (ORM) or data access layer.</li>
<li><strong>Key Distinction</strong>: <code>AddAsync</code> operates asynchronously, enhancing responsiveness in UI-centric applications by not blocking the UI thread. <code>Add</code> works synchronously, completing the operation in the current thread.</li>
</ul>
<h2 id="choosing-your-champion-addasync-vs-add"><a class="header" href="#choosing-your-champion-addasync-vs-add">Choosing Your Champion: AddAsync vs. Add</a></h2>
<p>Here's a breakdown to help you decide:</p>
<div class="table-wrapper"><table><thead><tr><th>Feature</th><th>AddAsync</th><th>Add</th></tr></thead><tbody>
<tr><td>Execution</td><td>Asynchronous</td><td>Synchronous</td></tr>
<tr><td>UI Responsiveness</td><td>Maintains responsiveness</td><td>Might block the UI thread</td></tr>
<tr><td>Use Cases</td><td>User interactions, background processes</td><td>Background tasks, immediate data processing</td></tr>
<tr><td>Performance (Network)</td><td>Potentially better for high latency networks</td><td>Might be slightly faster on local networks</td></tr>
<tr><td>Error Handling</td><td>Requires proper asynchronous error handling</td><td>Standard synchronous error handling</td></tr>
</tbody></table>
</div>
<h2 id="general-usage-and-examples"><a class="header" href="#general-usage-and-examples">General Usage and Examples</a></h2>
<ol>
<li>Adding an Entity (Asynchronous):</li>
</ol>
<pre><code class="language-csharp">// Assuming you have an instance of your repository (`repository)`)
// and a new Product object (`product`)
Task addProductTask = repository.AddAsync<Product>(product);
// Await the task to ensure completion before proceeding (optional)
await addProductTask;
// You can continue with further operations after successful addition
Console.WriteLine($"Product '{product.Name}' added successfully.");
</code></pre>
<ol start="2">
<li>Adding an Entity (Synchronous):</li>
</ol>
<pre><code class="language-csharp">repository.Add<Product>(product);
// No need to await as the operation happens synchronously
Console.WriteLine($"Product '{product.Name}' added successfully.");
</code></pre>
<h2 id="modern-usage-considerations"><a class="header" href="#modern-usage-considerations">Modern Usage Considerations</a></h2>
<ul>
<li><strong>Asynchronous Programming Paradigm</strong>: In modern applications, <code>AddAsync</code> is generally preferred due to its responsiveness benefits. Asynchronous programming allows your application to remain interactive while data is being added.</li>
<li><strong>Error Handling</strong>: Implement robust error handling mechanisms to gracefully handle potential exceptions during the addition process. Consider using try-catch blocks or asynchronous exception handling patterns (e.g., <code>Task.WaitAll</code> with exception propagation).</li>
<li><strong>Entity State Tracking</strong>: In some ORMs, calling <code>Add</code> might not automatically mark the entity as "added" for tracking purposes. Consult your ORM's documentation for configuration details regarding entity state management.</li>
</ul>
<h2 id="advanced-usage-scenarios"><a class="header" href="#advanced-usage-scenarios">Advanced Usage Scenarios</a></h2>
<ol>
<li>Adding Multiple Entities (Asynchronous):</li>
</ol>
<pre><code class="language-csharp">// Assuming you have a list of Product objects (`products`)
List<Task> addProductTasks = new List<Task>();
foreach (var product in products)
{
addProductTasks.Add(repository.AddAsync<Product>(product));
}
// Wait for all tasks to complete in parallel (or use other techniques like Task.WhenAll)
await Task.WaitAll(addProductTasks.ToArray());
Console.WriteLine($"{addProductTasks.Count} products added successfully.");
</code></pre>
<ol start="2">
<li>Adding Entities with Relationships (Eager Loading):</li>
</ol>
<p>If your entity model involves relationships, you might need to consider eager loading related entities to avoid multiple database queries. Consult your ORM's documentation for specific syntax and configuration options.</p>
<ol start="3">
<li>Adding Entities with Change Tracking (Optional):</li>
</ol>
<p>In some ORMs, enabling change tracking allows for efficient updates using methods like <code>UpdateAsync</code> or <code>Update</code>. Refer to your ORM's documentation for configuration details.</p>
<h2 id="remember-2"><a class="header" href="#remember-2">Remember:</a></h2>
<ul>
<li>Prioritize <code>AddAsync</code> for UI-centric applications to maintain responsiveness.</li>
<li>Choose <code>Add</code> for background tasks or scenarios where immediate data manipulation is critical.</li>
<li>Leverage asynchronous programming for a more modern and efficient approach.</li>
<li>Implement proper error handling and carefully consider entity state tracking in your ORM.</li>
<li>Explore advanced techniques like adding multiple entities, eager loading, and change tracking when necessary.</li>
</ul>
<p>By understanding the nuances of <code>AddAsync</code> and <code>Add</code>, you can effectively manage entity creation within your modern applications, ensuring responsiveness, efficiency, and error resilience.</p>
<div style="break-before: page; page-break-before: always;"></div><h2 id="understanding-addrangeasync-asynchronous-and-addrange-synchronous"><a class="header" href="#understanding-addrangeasync-asynchronous-and-addrange-synchronous">Understanding <code>AddRangeAsync</code> (Asynchronous) and <code>AddRange</code> (Synchronous)</a></h2>
<ul>
<li><strong>Core Purpose</strong>: Both methods empower you to add a collection of entities to your persistence layer (often a database) managed by your Object-Relational Mapper (ORM) or data access layer in a single operation.</li>
<li><strong>Key Distinction</strong>: <code>AddRangeAsync</code> operates asynchronously, enhancing responsiveness in UI-centric applications by not blocking the UI thread. <code>AddRange</code> works synchronously, completing the operation in the current thread.</li>
</ul>
<h2 id="choosing-your-champion-addrangeasync-vs-addrange"><a class="header" href="#choosing-your-champion-addrangeasync-vs-addrange">Choosing Your Champion: AddRangeAsync vs. AddRange</a></h2>
<p>Here's a breakdown to help you decide:</p>
<div class="table-wrapper"><table><thead><tr><th>Feature</th><th>AddRangeAsync</th><th>AddRange</th></tr></thead><tbody>
<tr><td>Execution</td><td>Asynchronous</td><td>Synchronous</td></tr>
<tr><td>UI Responsiveness</td><td>Maintains responsiveness</td><td>Might block the UI thread</td></tr>
<tr><td>Use Cases</td><td>User interactions, background processes</td><td>Background tasks, immediate data processing</td></tr>
<tr><td>Performance (Network)</td><td>Potentially better for high latency networks</td><td>Might be slightly faster on local networks</td></tr>
<tr><td>Error Handling</td><td>Requires proper asynchronous error handling</td><td>Standard synchronous error handling</td></tr>
</tbody></table>
</div>
<h2 id="general-usage-and-examples-1"><a class="header" href="#general-usage-and-examples-1">General Usage and Examples</a></h2>
<ol>
<li>Adding a Collection of Entities (Asynchronous):</li>
</ol>
<pre><code class="language-csharp">// Assuming you have an instance of your repository (`repository`)
// and a collection of Product objects (`products`)
Task addProductsTask = repository.AddRangeAsync<Product>(products);
// Await the task to ensure completion before proceeding (optional)
await addProductsTask;
// You can continue with further operations after successful addition
Console.WriteLine($"{products.Count} products added successfully.");
</code></pre>
<ol start="2">
<li>Adding a Collection of Entities (Synchronous):</li>
</ol>
<pre><code class="language-csharp">repository.AddRange<Product>(products);
// No need to await as the operation happens synchronously
Console.WriteLine($"{products.Count} products added successfully.");
</code></pre>
<h2 id="modern-usage-considerations-1"><a class="header" href="#modern-usage-considerations-1">Modern Usage Considerations:</a></h2>
<ul>
<li><strong>Asynchronous Programming Paradigm</strong>: In modern applications, <code>AddRangeAsyn</code> is generally preferred due to its responsiveness benefits. Asynchronous programming allows your application to remain interactive while data is being added.</li>
<li><strong>Error Handling</strong>: Implement robust error handling mechanisms to gracefully handle potential exceptions during the addition process. Use try-catch blocks or asynchronous error handling patterns (e.g., <code>Task.WaitAll</code> with exception propagation).</li>
<li><strong>Entity State Tracking</strong>: In some ORMs, calling <code>AddRange</code> might not automatically mark the entities as "added" for tracking purposes. Consult your ORM's documentation for configuration details regarding entity state management.</li>
</ul>
<h2 id="advanced-usage-scenarios-1"><a class="header" href="#advanced-usage-scenarios-1">Advanced Usage Scenarios</a></h2>
<ol>
<li>Adding Entities with Relationships (Eager Loading):</li>
</ol>
<p>If your entity model involves relationships, you might need to consider eager loading related entities to avoid multiple database queries. Consult your ORM's documentation for specific syntax and configuration options.</p>
<ol start="2">
<li>Adding Entities with Change Tracking (Optional):</li>
</ol>
<p>In some ORMs, enabling change tracking allows for efficient updates using methods like UpdateAsync or UpdateRange. Refer to your ORM's documentation for configuration details.</p>
<h2 id="additional-considerations-for-modern-applications"><a class="header" href="#additional-considerations-for-modern-applications">Additional Considerations for Modern Applications:</a></h2>
<ul>
<li><strong>Bulk Operations</strong>: Some ORMs might offer specialized bulk insertion methods for even greater performance when dealing with very large datasets.</li>
<li><strong>Batching</strong>: Consider breaking down massive collections into smaller batches for AddRangeAsync calls to manage memory usage and potential timeouts.</li>
<li><strong>Transactions</strong>: If your addition operation involves multiple entities and needs to be atomic (all succeed or all fail), utilize transactions provided by your ORM.</li>
</ul>
<h2 id="remember-3"><a class="header" href="#remember-3">Remember</a></h2>
<ul>
<li>Prioritize <code>AddRangeAsync</code> for UI-centric applications to maintain responsiveness when adding collections of entities.</li>
<li>Choose <code>AddRange</code> for background tasks or scenarios where immediate data manipulation is critical.</li>
<li>Leverage asynchronous programming for a more modern and efficient approach.</li>
<li>Implement proper error handling and carefully consider entity state tracking in your ORM.</li>
<li>Explore advanced techniques like eager loading, change tracking, bulk operations, batching, and transactions when necessary.</li>
</ul>
<p>By effectively using <code>AddRangeAsync</code> and <code>AddRange</code>, you can significantly improve the efficiency and scalability of your modern applications when bulk adding entities.</p>
<div style="break-before: page; page-break-before: always;"></div><h2 id="understanding-updateasync-asynchronous-and-update-synchronous"><a class="header" href="#understanding-updateasync-asynchronous-and-update-synchronous">Understanding <code>UpdateAsync</code> (Asynchronous) and <code>Update</code> (Synchronous):</a></h2>
<ul>
<li><strong>Core Purpose</strong>: Both methods empower you to modify existing entities within your persistence layer (often a database) managed by your Object-Relational Mapper (ORM) or data access layer.</li>
<li><strong>Key Distinction</strong>: <code>UpdateAsync</code> operates asynchronously, enhancing responsiveness in UI-centric applications by not blocking the UI thread. <code>Update</code> works synchronously, completing the operation in the current thread.</li>
</ul>
<h2 id="choosing-your-champion-updateasync-vs-update"><a class="header" href="#choosing-your-champion-updateasync-vs-update">Choosing Your Champion: UpdateAsync vs. Update</a></h2>
<p>Here's a breakdown to help you decide:</p>
<div class="table-wrapper"><table><thead><tr><th>Feature</th><th>UpdateAsync</th><th>Update</th></tr></thead><tbody>
<tr><td>Execution</td><td>Asynchronous</td><td>Synchronous</td></tr>
<tr><td>UI Responsiveness</td><td>Maintains responsiveness</td><td>Might block the UI thread</td></tr>
<tr><td>Use Cases</td><td>User interactions, background processes</td><td>Background tasks, immediate data processing</td></tr>
<tr><td>Performance (Network)</td><td>Potentially better for high latency networks</td><td>Might be slightly faster on local networks</td></tr>
<tr><td>Error Handling</td><td>Requires proper asynchronous error handling</td><td>Standard synchronous error handling</td></tr>
</tbody></table>
</div>
<h2 id="general-usage-and-examples-2"><a class="header" href="#general-usage-and-examples-2">General Usage and Examples:</a></h2>
<ol>
<li>Updating an Entity (Asynchronous):</li>
</ol>
<pre><code class="language-csharp">// Assuming you have an instance of your repository (`repository`)
// and a modified Product object (`modifiedProduct`)
Task updateProductTask = repository.UpdateAsync<Product>(modifiedProduct);
// Await the task to ensure completion before proceeding (optional)
await updateProductTask;
Console.WriteLine($"Product '{modifiedProduct.Name}' updated successfully.");
</code></pre>
<ol start="2">
<li>Updating an Entity (Synchronous):</li>
</ol>
<pre><code class="language-csharp">repository.Update<Product>(modifiedProduct);
// No need to await as the operation happens synchronously
Console.WriteLine($"Product '{modifiedProduct.Name}' updated successfully.");
</code></pre>
<h2 id="modern-usage-considerations-2"><a class="header" href="#modern-usage-considerations-2">Modern Usage Considerations</a></h2>
<ul>
<li><strong>Asynchronous Programming Paradigm</strong>: In modern applications, <code>UpdateAsync</code> is generally preferred due to its responsiveness benefits. Asynchronous programming allows your application to remain interactive while data is being updated.</li>
<li><strong>Change Tracking</strong>: Many ORMs rely on change tracking to identify which properties of an entity have been modified. Ensure your ORM has change tracking enabled for <code>UpdateAsync </code>and <code>Update</code> to work effectively. Refer to your ORM's documentation for configuration details.</li>
<li><strong>Detached Entities</strong>: If you're working with entities that haven't been loaded from the database (detached entities), you might need to attach them to the context before calling <code>UpdateAsync</code> or <code>Update</code>. Consult your ORM's documentation for specific guidance on attaching entities.</li>
<li><strong>Optimistic Concurrency</strong>: Implement optimistic concurrency control if your application allows multiple users to modify the same entity simultaneously to prevent data inconsistencies. This often involves leveraging properties like timestamps or version numbers within your entity model.</li>
</ul>
<h2 id="advanced-usage-scenarios-2"><a class="header" href="#advanced-usage-scenarios-2">Advanced Usage Scenarios</a></h2>
<ol>
<li>Updating Entities with Relationships:</li>
</ol>
<p>Updating entities with relationships might involve cascading updates to related entities. Consult your ORM's documentation for configuration options and potential performance considerations.</p>
<ol start="2">
<li>Updating Multiple Entities:</li>
</ol>
<p>Some ORMs offer bulk update operations for improved performance when dealing with large datasets. Research methods like <code>UpdateRangeAsync</code> or <code>UpdateRange</code> provided by your ORM.</p>
<h2 id="remember-4"><a class="header" href="#remember-4">Remember</a></h2>
<ul>
<li>Prioritize <code>UpdateAsync</code> for UI-centric applications to maintain responsiveness when updating entities.</li>
<li>Choose <code>Update</code> for background tasks or scenarios where immediate confirmation of update success is crucial.</li>
<li>Leverage asynchronous programming for a more modern and efficient approach.</li>
<li>Ensure change tracking is enabled in your ORM and consider attaching detached entities if necessary.</li>
<li>Implement optimistic concurrency control for scenarios with potential concurrent modifications.</li>
<li>Explore advanced techniques like bulk updates and relationship handling depending on your ORM and use case.</li>
</ul>
<p>By effectively using <code>UpdateAsync</code> and <code>Update</code>, you can streamline the process of modifying data within your modern applications, ensuring responsiveness and data consistency.</p>
<div style="break-before: page; page-break-before: always;"></div><h2 id="understanding-updaterangeasync-asynchronous-and-updaterange-synchronous"><a class="header" href="#understanding-updaterangeasync-asynchronous-and-updaterange-synchronous">Understanding <code>UpdateRangeAsync</code> (Asynchronous) and <code>UpdateRange</code> (Synchronous):</a></h2>
<ul>
<li><strong>Core Purpose</strong>: Both methods empower you to efficiently modify a collection of entities within your persistence layer (often a database) managed by your Object-Relational Mapper (ORM) or data access layer in a single operation.</li>
<li><strong>Key Distinction</strong>: <code>UpdateRangeAsync</code> operates asynchronously, enhancing responsiveness in UI-centric applications by not blocking the UI thread. <code>UpdateRange</code> works synchronously, completing the operation in the current thread.</li>
</ul>
<h2 id="choosing-your-champion-updaterangeasync-vs-updaterange"><a class="header" href="#choosing-your-champion-updaterangeasync-vs-updaterange">Choosing Your Champion: <code>UpdateRangeAsync</code> vs. <code>UpdateRange</code></a></h2>
<p>Here's a breakdown to help you decide:</p>
<div class="table-wrapper"><table><thead><tr><th>Feature</th><th>UpdateRangeAsync</th><th>UpdateRange</th></tr></thead><tbody>
<tr><td>Execution</td><td>Asynchronous</td><td>Synchronous</td></tr>
<tr><td>UI Responsiveness</td><td>Maintains responsiveness</td><td>Might block the UI thread</td></tr>
<tr><td>Use Cases</td><td>User interactions, background processes</td><td>Background tasks, immediate data processing</td></tr>
<tr><td>Performance (Network)</td><td>Potentially better for high latency networks</td><td>Might be slightly faster on local networks</td></tr>
<tr><td>Error Handling</td><td>Requires proper asynchronous error handling</td><td>Standard synchronous error handling</td></tr>
</tbody></table>
</div>
<h2 id="general-usage-and-examples-3"><a class="header" href="#general-usage-and-examples-3">General Usage and Examples:</a></h2>
<ol>
<li>Updating a Collection of Entities (Asynchronous):</li>
</ol>
<pre><code class="language-csharp">// Assuming you have an instance of your repository (`repository`)
// and a collection of modified Product objects (`modifiedProducts`)
Task updateProductsTask = repository.UpdateRangeAsync<Product>(modifiedProducts);
// Await the task to ensure completion before proceeding (optional)
await updateProductsTask;
Console.WriteLine($"{modifiedProducts.Count} products updated successfully.");
</code></pre>
<ol start="2">
<li>Updating a Collection of Entities (Synchronous):</li>
</ol>
<pre><code class="language-csharp">repository.UpdateRange<Product>(modifiedProducts);
// No need to await as the operation happens synchronously
Console.WriteLine($"{modifiedProducts.Count} products updated successfully.");
</code></pre>
<h2 id="modern-usage-considerations-3"><a class="header" href="#modern-usage-considerations-3">Modern Usage Considerations</a></h2>
<ul>
<li><strong>Asynchronous Programming Paradigm</strong>: In modern applications, <code>UpdateRangeAsync</code> is generally preferred due to its responsiveness benefits. Asynchronous programming allows your application to remain interactive while data is being updated.</li>
<li><strong>Change Tracking</strong>: Many ORMs rely on change tracking to identify modified properties within entities. Ensure change tracking is enabled for <code>UpdateRangeAsync</code> and <code>UpdateRange</code> to work effectively. Refer to your ORM's documentation for configuration details.</li>
<li><strong>Detached Entities</strong>: If you're working with detached entities (not loaded from the database), you might need to attach them to the context before calling <code>UpdateRangeAsync</code> or <code>UpdateRange</code>. Consult your ORM's documentation for specific guidance on attaching entities.</li>
<li><strong>Optimistic Concurrency</strong>: Implement optimistic concurrency control if your application allows multiple users to modify the same entities simultaneously to prevent data inconsistencies. This often involves leveraging properties like timestamps or version numbers within your entity model.</li>
</ul>
<h2 id="advanced-usage-scenarios-in-modern-applications"><a class="header" href="#advanced-usage-scenarios-in-modern-applications">Advanced Usage Scenarios in Modern Applications</a></h2>
<ol>
<li>Updating Entities with Relationships:</li>
</ol>
<p>Updating entities with relationships might involve cascading updates to related entities. Consult your ORM's documentation for configuration options and potential performance considerations. Here are some modern approaches:</p>
<ul>
<li><strong>Eager Loading</strong>: Load related entities when fetching data to minimize subsequent database queries.</li>
<li><strong>Explicit Configuration</strong>: Define how your ORM should handle relationship updates through configuration options provided by your ORM.</li>
</ul>
<ol start="2">
<li>Updating Large Datasets:</li>
</ol>
<ul>
<li><strong>Bulk Operations</strong>: Some ORMs offer specialized bulk update methods for enhanced performance when dealing with very large datasets. Research methods like <code>BulkUpdateAsync</code> or <code>BulkUpdate</code> provided by your ORM.</li>
<li><strong>Batching</strong>: Consider breaking down massive collections into smaller batches for <code>UpdateRangeAsync</code> calls to manage memory usage and potential timeouts.</li>
</ul>
<h2 id="remember-5"><a class="header" href="#remember-5">Remember</a></h2>
<ul>
<li>Prioritize <code>UpdateRangeAsync</code> for UI-centric applications to maintain responsiveness when updating multiple entities.</li>
<li>Choose <code>UpdateRange</code> for background tasks or scenarios where immediate confirmation of update success is critical.</li>
<li>Leverage asynchronous programming for a more modern and efficient approach.</li>
<li>Ensure change tracking is enabled in your ORM and consider attaching detached entities if necessary.</li>
<li>Implement optimistic concurrency control for scenarios with potential concurrent modifications.</li>
<li>Explore advanced techniques like eager loading, explicit configuration, bulk operations, and batching for performance optimization in modern applications.</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h2 id="understanding-removeasync-and-remove"><a class="header" href="#understanding-removeasync-and-remove">Understanding RemoveAsync and Remove</a></h2>
<ul>
<li><strong>Core Purpose</strong>: Both methods serve the purpose of deleting existing entities from your persistence layer (often a database) managed by your Object-Relational Mapper (ORM) or data access layer.</li>
<li><strong>Key Distinction</strong>: <code>RemoveAsync</code> operates asynchronously, enhancing responsiveness in UI-centric applications by not blocking the UI thread. <code>Remove</code> works synchronously, completing the operation in the current thread.</li>
</ul>
<h2 id="choosing-your-champion-asynchronous-vs-synchronous"><a class="header" href="#choosing-your-champion-asynchronous-vs-synchronous">Choosing Your Champion: Asynchronous vs. Synchronous</a></h2>
<p>Here's a breakdown to help you decide:</p>
<div class="table-wrapper"><table><thead><tr><th>Feature</th><th>RemoveAsync</th><th>Remove</th></tr></thead><tbody>
<tr><td>Execution</td><td>Asynchronous</td><td>Synchronous</td></tr>
<tr><td>UI Responsiveness</td><td>Maintains responsiveness</td><td>Might block the UI thread</td></tr>
<tr><td>Use Cases</td><td>User interactions, background processes</td><td>Background tasks, immediate data processing</td></tr>
<tr><td>Performance (Network)</td><td>Potentially better for high latency networks</td><td>Might be slightly faster on local networks</td></tr>
<tr><td>Error Handling</td><td>Requires proper asynchronous error handling</td><td>Standard synchronous error handling</td></tr>
</tbody></table>
</div>
<h2 id="general-usage-and-examples-4"><a class="header" href="#general-usage-and-examples-4">General Usage and Examples</a></h2>
<ol>
<li>Deleting an Entity (Asynchronous):</li>
</ol>
<pre><code class="language-csharp">// Assuming you have an instance of your repository (`repository`)
// and an entity to delete (`productToDelete`)
Task removeProductTask = repository.RemoveAsync<Product>(productToDelete);
// Await the task to ensure completion before proceeding (optional)
await removeProductTask;
Console.WriteLine($"Product '{productToDelete.Name}' deleted successfully.");
</code></pre>
<ol start="2">
<li>Deleting an Entity (Synchronous):</li>
</ol>
<pre><code class="language-csharp">repository.Remove<Product>(productToDelete);
// No need to await as the operation happens synchronously
Console.WriteLine($"Product '{productToDelete.Name}' deleted successfully.");
</code></pre>
<h2 id="modern-usage-considerations-4"><a class="header" href="#modern-usage-considerations-4">Modern Usage Considerations</a></h2>
<ul>
<li><strong>Asynchronous Programming Paradigm</strong>: In modern applications, <code>RemoveAsync</code> is generally preferred due to its responsiveness benefits. Asynchronous programming allows your application to remain interactive while data is being deleted.</li>
<li><strong>Entity State Tracking</strong>: Many ORMs rely on entity state tracking to determine which entities need to be deleted. Ensure entity state tracking is enabled for <code>RemoveAsync</code> and <code>Remove</code> to work effectively. Refer to your ORM's documentation for configuration details.</li>
<li><strong>Cascading Deletes</strong>: If your entity model involves relationships with cascading deletes (deleting related entities when a parent entity is deleted), configure your ORM appropriately.</li>
<li><strong>Optimistic Concurrency</strong>: Implement optimistic concurrency control if your application allows multiple users to delete the same entity simultaneously to prevent data inconsistencies (often using timestamps or version numbers).</li>
</ul>
<h2 id="advanced-usage-scenarios-in-modern-applications-1"><a class="header" href="#advanced-usage-scenarios-in-modern-applications-1">Advanced Usage Scenarios in Modern Applications</a></h2>
<ol>
<li>Deleting Entities with Relationships:</li>
</ol>
<p>Deletion of entities with relationships might involve cascading deletes to related entities. Consult your ORM's documentation and configure cascading behavior as needed. Here are some modern approaches:
- <strong>Explicit Configuration</strong>: Define how your ORM should handle related entity deletions through configuration options provided by your ORM.
- <strong>Soft Deletes</strong>: Instead of permanent deletion, consider marking entities as "deleted" to maintain a historical record.</p>
<ol start="2">
<li>Deleting Large Datasets:
<ul>
<li><strong>Bulk Operations</strong>: Some ORMs offer specialized bulk delete methods for improved performance when dealing with very large datasets. Research methods like BulkDeleteAsync or BulkDelete provided by your ORM.</li>
<li><strong>Batching</strong>: Consider breaking down massive collections into smaller batches for RemoveAsync calls to manage memory usage and potential timeouts.</li>
</ul>
</li>
</ol>
<h2 id="remember-6"><a class="header" href="#remember-6">Remember</a></h2>
<ul>
<li>Prioritize <code>RemoveAsync</code> for UI-centric applications to maintain responsiveness when deleting entities.</li>
<li>Choose <code>Remove</code> for background tasks or scenarios where immediate confirmation of deletion success is critical.</li>
<li>Leverage asynchronous programming for a more modern and efficient approach.</li>
<li>Ensure entity state tracking is enabled in your ORM and consider cascading deletes or soft deletes depending on your use case.</li>
<li>Implement optimistic concurrency control for scenarios with potential concurrent modifications.</li>
<li>Explore advanced techniques like explicit configuration, soft deletes, bulk operations, and batching for performance optimization in modern applications.</li>
</ul>
<div style="break-before: page; page-break-before: always;"></div><h2 id="understanding-removerangeasync-and-removerange"><a class="header" href="#understanding-removerangeasync-and-removerange">Understanding RemoveRangeAsync and RemoveRange</a></h2>
<ul>
<li><strong>Core Purpose</strong>: Both methods empower you to efficiently delete a collection of entities from your persistence layer (often a database) managed by your Object-Relational Mapper (ORM) or data access layer in a single operation.</li>
<li><strong>Key Distinction</strong>: <code>RemoveRangeAsync</code> operates asynchronously, enhancing responsiveness in UI-centric applications by not blocking the UI thread. <code>RemoveRange</code> works synchronously, completing the operation in the current thread.</li>
</ul>
<h2 id="choosing-your-champion-asynchronous-vs-synchronous-1"><a class="header" href="#choosing-your-champion-asynchronous-vs-synchronous-1">Choosing Your Champion: Asynchronous vs. Synchronous</a></h2>
<p>Here's a breakdown to help you decide:</p>
<div class="table-wrapper"><table><thead><tr><th>Feature</th><th>RemoveRangeAsync</th><th>RemoveRange</th></tr></thead><tbody>
<tr><td>Execution</td><td>Asynchronous</td><td>Synchronous</td></tr>
<tr><td>UI Responsiveness</td><td>Maintains responsiveness</td><td>Might block the UI thread</td></tr>
<tr><td>Use Cases</td><td>User interactions, background processes</td><td>Background tasks, immediate data processing</td></tr>
<tr><td>Performance (Network)</td><td>Potentially better for high latency networks</td><td>Might be slightly faster on local networks</td></tr>
<tr><td>Error Handling</td><td>Requires proper asynchronous error handling</td><td>Standard synchronous error handling</td></tr>
</tbody></table>
</div>
<h2 id="general-usage-and-examples-5"><a class="header" href="#general-usage-and-examples-5">General Usage and Examples</a></h2>
<ol>
<li>Deleting a Collection of Entities (Asynchronous):</li>