دوره آموزشی Entity FrameWork Core - قسمت 21

دوره آموزشی Entity FrameWork Core - قسمت بیستممفهوم Client vs. Server Querying Evaluation :به عنوان یک قاعده کلی، Entity Framework Core سعی می کند تا حد امکان یک پرس و جو را در Server ارزیابی کند. EF Core بخش هایی از پرس و جو را به پارامترهایی تبدیل می کند که می تواند در سمت Client ارزیابی شود.Client evaluation in the top-level projection :مفهوم projection : راهی برای نگاشت یک مجموعه از ویژگی ها به دیگری است. در رابطه با Entity Framework، این روشی برای ترجمه یک موجودیت کامل (جدول پایگاه داده) به یک کلاس #C با زیرمجموعه ای از آن ویژگی ها است. مقادیر را نیز می توان altered/joined/removed کرد.در مثال زیر، از یک متد کمکی برای استانداردسازی URLها برای blogها استفاده شده است که از پایگاه داده SQL Server بازگردانده می شوند.var blogs = context.Blogs .OrderByDescending(blog => blog.Rating) .Select( blog => new { Id = blog.BlogId, Url = StandardizeUrl(blog.Url) }) .ToList();و این هم متد StandardizeUrl :public static string StandardizeUrl(string url) { url = url.ToLower(); if (!url.StartsWith(&quothttp://&quot)) { url = string.Concat(&quothttp://&quot, url); } return url; }از آنجایی که SQL Server provider هیچ بینشی در مورد نحوه پیاده سازی این متد ندارد، امکان ترجمه آن به SQL وجود ندارد. تمام جنبه های دیگر پرس و جو در پایگاه داده ارزیابی می شوند، اما ارسال URL برگشتی از طریق این متد بر روی client انجام می شود.Unsupported client evaluation :در حالی که ارزیابی client مفید است، گاهی اوقات می تواند منجر به عملکرد ضعیف شود. پرس و جوی زیر را در نظر بگیرید که در آن اکنون از متد کمکی متد StandardizeUrl در فیلتر Where استفاده می شود. از آنجایی که فیلتر را نمی توان در پایگاه داده اعمال کرد، تمام داده ها باید به حافظه کشیده شوند تا فیلتر روی client اعمال شود. بر اساس فیلتر و مقدار داده روی server، ارزیابی client می تواند منجر به عملکرد ضعیف شود. بنابراین Entity Framework Core چنین ارزیابی client را مسدود می کند و یک استثنا در زمان اجرا ایجاد می کند.var blogs = context.Blogs .Where(blog => StandardizeUrl(blog.Url).Contains(&quotdotnet&quot)) .ToList();Explicit client evaluation :ممکن است در موارد خاصی مانند زیر به صراحت نیاز به client evaluation داشته باشیدحجم داده ها کم است به طوری که client evaluation جریمه عملکرد زیادی را متحمل نمی شود.اپراتور LINQ مورد استفاده ترجمه سمت server ندارد.در چنین مواردی، می‌توانید صریحاً با فراخوانی متدهایی مانند AsEnumerable یا ToList (AsAsyncEnumerable یا ToListAsync برای async) ارزیابی client را انتخاب کنید.سوال :» استفاده از AsEnumerable یا ToList در شرایط مختلف کدام را انتخاب می کنید ؟var blogs = context.Blogs .AsEnumerable() .Where(blog => StandardizeUrl(blog.Url).Contains(&quotdotnet&quot)) .ToList();با استفاده از AsEnumerable می‌توانید نتایج را streaming کنید، اما استفاده از ToList با ایجاد یک لیست باعث ایجاد buffering می‌شود، که حافظه اضافی را نیز می‌گیرد. اگرچه اگر چندین بار enumerating می کنید، ذخیره نتایج در یک لیست کمک بیشتری می کند زیرا فقط یک پرس و جو وجود دارد.خوب شاید بپرسدید streaming و buffering به چه معنا هستند ؟ خوب buffering به بارگیری تمام نتایج پرس و جو در حافظه اشاره دارد، در حالی که streaming به این معنی است که EF هر بار یک نتیجه را به برنامه تحویل می دهد و هرگز کل مجموعه نتایج را در حافظه ندارد. اینکه یک پرس و جو buffering می شود یا streaming می یابد بستگی به نحوه ارزیابی آن دارد:در اینجا ToList و ToArray باعث می شوند که کل مجموعه نتایج بافر شود :// ToList and ToArray cause the entire resultset to be buffered: var blogsList = context.Posts.Where(p => p.Title.StartsWith(&quotA&quot)).ToList(); var blogsArray = context.Posts.Where(p => p.Title.StartsWith(&quotA&quot)).ToArray(); // Foreach streams, processing one row at a time: foreach (var blog in context.Posts.Where(p => p.Title.StartsWith(&quotA&quot))) { // ... }و AsEnumerable همچنین streaming می کند و به شما امکان می دهد عملگرهای LINQ را در سمت کلاینت اجرا کنید:var doubleFilteredBlogs = context.Posts .Where(p => p.Title.StartsWith(&quotA&quot)) // Translated to SQL and executed in the database .AsEnumerable() .Where(p => SomeDotNetMethod(p)); // Executed at the client on all database resultsخلاصه اینکه اگر درخواست‌های شما تعداد کمی ردیف را بر می گرداند، احتمالاً لازم نیست نگران استفاده از AsEnumerable یا ToList باشید. با این حال، اگر درخواست شما ممکن است تعداد زیادی ردیف را برگرداند، ارزش آن را دارد که به جای buffering ، به streaming فکر کنید.بیشتر بخوانید : دوره آموزشی Entity FrameWork Core - قسمت 22بیشتر بخوانید : دوره آموزشی Entity FrameWork Coreبیشتر بخوانید : نقشه راه توسعه دهندگان Asp.NET Corehttps://zarinp.al/farshidazizi