Linq To Entity یک ORM بسیار قدرتمند است که برای کوئری نویسی و مدیریت دیتابیس استفاده می شود. از آنجایی که این ابزار امکانات بسیار زیادی را در اختیار برنامه نویس گذاشته است بیش از هر چیز باید نکاتی را بدانیم که با رعایت آنها می توانیم بهترین عملکرد و کارایی (Performance) را از این ORM بدست آوریم. دانستن این نکات به ما کمک می کند تا با رعایت کردن آنها بهترین عملکرد را در سرعت و کارایی برای برنامه خود به ارمغان بیاوریم. در این مقاله به برخی از مهم ترین مواردی که می توان به سادگی آنها را رعایت کرد و با استفاده از آنها، افزایش کارایی Entity Framework را تحقق بخشید، می پردازیم.
همانطور که می دانید مدل (Entity Model) شامل داده هایی است که کاربر با آنها سروکار دارد. این مدل می تواند شامل کلاس هایی باشد که از آنها به عنوان View Model یاد می شود و هر کدام نماینده یک جدول از دیتابیس است یا می تواند شامل کلاس هایی باشد که منطق انجام کار، قوانین اعتبارسنجی و تبدیل داده ها به فرمت مناسب و... را انجام می دهند که در این صورت به آن ها Domain Model گفته می شود. در هر صورت باید Entityt Model یک قسمت از واحد کاری شما باشد. اگر دیتابیس شما اشیایی دارد که همگی با یکدیگر در ارتباط نیستند، لزومی ندارد همه را در یک مدل قرار دهید، چرا که همه مدل را در حافظه قرار دادن در حالی که از بسیاری از اشیاء آن استفاده نمی کنیم کار اشتباهی است و این کار باعث کاهش کارایی برنامه می شود.
بنابراین تنها کلاس هایی را که به یگدیگر مرتبط هستند، در یک مدل قرار دهید.
Change Tracking یکی از ویژگی های EntityFramwork است. زمانی که یک رکورد ار دیتابیس یا لیستی از رکوردهای دیتابیس را بازیابی می کنید (EF (EntityFramework یک کپی از آن ها را در حافظه خود نگه می دارد. دلیل این امر در وهله اول این است که بتواند تغییراتی را که شما اعمال می کنید، با نسخه اولیه مقایسه کند. اما این کار تنها زمانی خوب است که بخواهیم ویرایشی انجام دهیم. بنابراین زمانی که داده هایی را تنها جهت نمایش از دیتابیس بازیابی می کنید، بهتر است که صراحتا این موضوع را به EF اعلام کنید
NorthwindDataContext context = new NorthwindDataContext() context.tblCities.MergeOption = MergeOption.NoTracking;
و یا بصورت زیر به ازای هر کوئری می توانیم عمل کنیم:
var compare = (from itemFlowSubject in context.FlowSubject where itemFlowSubject.FlowIdref == id select itemsubject).AsNoTracking().ToList();
زمانی که شی ای از objectContext در برنامه برای اولین بار ساخته می شود، EF مجموعه از کلاس ها را که برای دسترسی به دیتابیس لازم است، ایجاد می کند. این کلاس ها در واقع ایجاد کننده همان View های برنامه هستند. اگر Model شما بزرگ باشد، ایجاد این کلاس ها ممکن است وقفه ای در پاسخ دهی برنامه در اولین درخواست برای هر صفحه بوحود آورد. ما می توانیم این زمان پاسخ دهی را با ایجاد T4 Template کاهش دهیم. T4 Template ها View های کامپایل شده آماده ای هستند که در زمان نیاز فقط اجرا می شوند.
تصور کنید جدول Customer دارای بیست فیلد است که ما فقط یه فیلد CustomerID, Name, Address آن را احتیاج داریم
//کار اشتباهvar customer = (from cust in dataContext.Customers select cust).ToList(); //کار درستvar customer = (from cust in dataContext.Customers select new { customer. CustomerID, customer.Name, customer.Address }). ToList ();
در Linq ما انواع مختلفی از مجموعه ها مانند Var, IEnumerable, IQueryable, IList برای کار با داده ها داریم. هر مجموعه اهمیت و تأثیر متفاوتی بر روی یک کوئری دارد. بنابراین در استفاده از این مجموعه ها برای کار با داده های مختلف مراقب باشید.
کوئری ها در Linq هر بار که برای اولین بار اجرا می شوند روندی را طی می کنند تا به دستورات SQL تبدیل شوند. شما می توانید با ایجاد کوئری های کامپایل شده، سرعت اجرای کد را بالا ببرید. معمولا این کار را برای کوئری هایی انجام می دهند که بارها و بارها ممکن است در صفحه استفاده شوند ولی محتوای آنها تغییر نمی کند، مانند لیستی از شهرها و استان ها.
// ایجاد یک شی EntittyNorthwindEntities mobjentity = new NorthwindEntities(); //ایجاد یک کوئریIQueryable lstCus = from customer in mobjentity.tblCustomerswhere customer.City == "Delhi"select customer; //کامپایل کردن کوئریFunc> compiledQuery= CompiledQuery.Compile>((ctx, city) =>from customer in ctx.Customerswhere customer.City == cityselect customer);
این مورد بیشتر در زمان صفحه بندی گریدها و لیست ها اتفاق می افتد. بهتر است هر بار همان تعداد رکوردی را که برای نمایش یک صفحه از گرید لازم است، بازیابی کنیم. مثال زیر چگونگی انجام این کار را نشان می دهد:
// create the entity objectNorthwindEntities mobjentity = new NorthwindEntities();int pageSize=10,startingPageIndex=2;List lstCus = mobjentity.tblCustomers.Take(pageSize) .Skip(startingPageIndex * pageSize) .ToList();
در Linq زمانی که از متد Contains استفاده می کنیم، این متد تبدیل به شرط "WHRE IN" در SQL می شود که به شدت کارایی را پایین می آورد.
Viewها در Linq به شدت کارایی کوئری را پایین می آورند. بنابراین تا حد ممکن از استفاده از View در دستورات Linq خودداری کنید.
برای مشاهده نتایج و بهینه سازی کوئری های Linq می توانید از ابزاری به نام LinqPad استفاده کنید. این ابزار برای ساخت پرس و جو، اشکال زدایی و بهینه سازی بسیار مفید است.
منبع: سایت Dot Net Tricks
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.