KeudellCoding / Blazor.AdvancedBlazorSelect2

Simple wrapper for Select2 with full support of databases and custom web APIs.
https://www.nuget.org/packages/KeudellCoding.Blazor.AdvancedBlazorSelect2/
MIT License
16 stars 4 forks source link

DbSet Optimization #4

Open kanadaj opened 3 years ago

kanadaj commented 3 years ago

Describe the bug The code uses IEnumerable<TItem>.Count() in OnInitialized(), which causes a full on SELECT * FROM Table then counts the resulting elements inside the materialized list. In a larger database this can cause extreme memory usage and loading times.

Expected behavior Check if the data source is IQueryable<TItem>, and if it is, call it using the appropriate extension method on IQueryable<TItem> to result in the correct query. That said, if it's IQueryable<TItem>, might as well just set MinimumInputLength to 1 anyway.

kanadaj commented 3 years ago

For anyone else looking to use this, here is a quick patch that doesn't need you to copy the entire code base:

    public class Select2<TItem, TSource> : KeudellCoding.Blazor.AdvancedBlazorSelect2.Select2<TItem, TSource> where TSource : IEnumerable<TItem> where TItem : class
    {
        protected override void OnInitialized()
        {
            if (Datasource is IQueryable<TItem> queryable)
            {
                if (queryable.Count() > MaxItemsPerPage)
                {
                    Select2Options.MinimumInputLength = 1;   
                }
                var fieldRef = typeof(KeudellCoding.Blazor.AdvancedBlazorSelect2.Select2<TItem, TSource>).GetField("dotNetRef", BindingFlags.NonPublic | BindingFlags.Instance);
                fieldRef.SetValue(this, DotNetObjectReference.Create(this as KeudellCoding.Blazor.AdvancedBlazorSelect2.Select2<TItem, TSource>));
            }
            else
            {
                base.OnInitialized();
            }
        }
    }