نگاهی به کیفیت LinkedIn Tips
نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۲/۱۷ ۱۱:۳۷
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
AsEnumerable()، عملکرد بهتری نسبت به قطعه کد اول که از متد ToList() استفاده میکند، دارد.var users = context.Users.ToList().Where(u => u.IsActive);
Users از پایگاه داده به حافظه کلاینت (Client) منتقل شده و به صورت یک لیست (List<User>) در میآیند. سپس، متد Where() بر روی این لیستِ درون حافظه اجرا شده و کاربرانی که ویژگی IsActive آنها true است، فیلتر میشوند. واضح است که این روش، به خصوص در مواجهه با جداول بزرگ، بسیار ناکارآمد است زیرا حجم زیادی از دادههای غیرضروری به حافظه منتقل شده و سربار زیادی را ایجاد میکند.var users = context.Users.AsEnumerable().Where(u => u.IsActive);
AsEnumerable() و بازگرداندن IEnumerable<User>، عملکرد بهتری دارد. درک نادرست اینجاست که متد AsEnumerable() در چارچوب Entity Framework، اجرای کوئری (Query) را از سطح پایگاه داده به سطح کلاینت منتقل میکند. به عبارت دیگر، با فراخوانی AsEnumerable()، شما به Entity Framework میگویید که هرگونه عملیات LINQ (Language Integrated Query) که پس از آن میآید، باید در حافظه برنامه شما (کلاینت) اجرا شود، نه در پایگاه داده (سرور). در نتیجه، حتی با وجود اینکه نوع بازگشتی IEnumerable<User> است و ممکن است تا زمان نیاز واقعی به دادهها، عمل واکشی به تعویق بیفتد (Deferred Execution)، باز هم کل جدول Users به حافظه کلاینت منتقل خواهد شد تا فیلتر Where() روی آن اعمال شود.List<User> در مقابل IEnumerable<User>). از آنجایی که IEnumerable یک مجموعه رو به جلو (Forward-Only Collection) است، ممکن است در سناریوهای خاص و تا قبل از فراخوانی متدهایی مانند ToList() یا تکرار کامل آن، مقدار کمی سربار اولیه کمتری داشته باشد. با این حال، در یک برنامه کاربردی ASP.NET Core، هنگام تلاش برای نمایش یا استفاده از این IEnumerable، چارچوب به طور خودکار آن را Materialize (تبدیل به یک مجموعه قابل استفاده) میکند و در نتیجه، همان مشکل انتقال کل دادهها به حافظه رخ خواهد داد.Where() قبل از فراخوانی متدهایی مانند ToList() یا ToArray() انجام میشود.var users = context.Users.Where(u => u.IsActive).ToList();
u => u.IsActive به عنوان بخشی از کوئری SQL (Structured Query Language) به پایگاه داده ارسال میشود. پایگاه داده تنها رکوردهایی را برمیگرداند که این شرط را برآورده میکنند. در نتیجه، حجم دادههای منتقل شده به حافظه کلاینت به حداقل رسیده و عملکرد برنامه به طور قابل توجهی بهبود مییابد، به خصوص در کار با جداول بزرگ.ToList() و AsEnumerable() میتواند منجر به بارگذاری غیرضروری حجم زیادی از دادهها در حافظه و کاهش عملکرد برنامه شود. راهکار صحیح، اعمال فیلترها در سطح کوئری و قبل از واکشی دادهها از پایگاه داده است. همچنین، ضروری است که توسعهدهندگان با دیدی انتقادی به مطالب آموزشی آنلاین نگاه کرده و همواره به دنبال منابع معتبر برای کسب اطلاعات باشند.