PDA

View Full Version : 7 روش برای افزایش کارایی Entity Framework



ali_72
پنج شنبه 14 اسفند 1393, 07:34 صبح
سلام
دوستان آقای نصیری در سایتشون این لینک را قرار دادند:
http://www.talksharp.com/increase-enity-framework-performance
تسلط من به زبان خوب نیست و یک سری موارد که در اینجا گفته شده بود به صورت کامل متوجه نشدم چکیده صفحه فوق رو اینجا میذارم و یک سری سوال دارم که دوستان اگه راهنمایی کنند ممنون میشم.

7 روش برای افزایش کارایی Entity Framework :
http://www.talksharp.com/increase-enity-framework-performance
1- استفاده نکردن از repository pattern
2- صفحه بندی
3- تنها فیلدهایی که نیاز دارید را انتخاب کنید در کوئری و به خاطر خواستن چند فیلد تمام دیتاها را لود نکنید.
4- استفاده از virtual در کلاس های پایگاه داده
5- بهتر است زمانیکه نمی خواهید در لیستی که از پایگاه داده گرفتید تغییری ایجاد کنید از تابع AsNoTracking استفاده کنید.
_context.Posts.AsNoTracking().ToList();

6- استفاده از ایندکس ها: مثلا زمانیکه شما یک لیست از کاربران دارید و ایمیل در این لیست برای هر کاربر یکتا است شما می توانید با ایندکس قرار دادن فیلد ایمیل به سرعت واکشی اطلاعات از پایگاه داده کمک کنید.
CreateIndex(table: "dbo.Users", column: "Email", unique: true, name: "UIX_Email");

7- کاهش تعداد کوئری ها

حالا سوال های من:
در مورد مورد 4 : من برای تمام فیلدهای کلاس ها پایگاه داده از virtual استفاده میکنم. کجا نباید استفاده کرد؟ (در این سایت یه توضیحی داده که متوجه نشدم)
در مورد مورد 5: در بسیاری موارد لیستی که از پایگاه داده جستجو می کنیم نیاز به تغییرات نداره یعنی در همه جا از AsNoTracking قبل از toList استفاده کنیم؟ کجا نباید استفاده کنیم؟ (در این سایت یه توضیحی داده که متوجه نشدم)
6- به طور معمول من فیلد id را کلید قرار میدم با قرار دادن [key] در بالای تعریف پراپرتی id در کلاس های پایگاه داده. زمانیکه من چند کلید داشته باشم باید چه کنم؟
7- متوجه منظور نویسنده نشدم

aroshanzamir
پنج شنبه 14 اسفند 1393, 08:57 صبح
سلام وقت شما بخیر :
مورد 4 خیلی مهم است باز هم در مورد این مطلب استاد نصیری در لابه لای مطالب سایت خودشون مطالبی را گفته اند : ولی در اینجا :
وقتی که شما ارتباطات را با کلمه کلیدی virtual تعریف می کنید Entity از LazLoading استفاده می کند منظور : object relation ها load نخواهند شد تا وقتی که مورد نیاز باشند یا اولین بار که دستیابی به آنها صورت گیرد.. LazLoading ایده خوبی می باشد اما می تواند کارایی را کاهش دهد چون تعداد بیشتری رفت و برگشت به پایگاه داده وجود دارد و در صورتی که شما دقت نکنید LazLoading می تواند باعث Select N+1 شود شما می توانید LazLoading را خاموش کنید تا از LazLoading و Select N+1 جلوگیری کنید ...

نکته : مثلا در صورتی که یک جدول استان و یک جدول شهرستان داشته باشید در زمان فراخوانی اطلاعات با ارتباطات حتما از Include استفاده نمایید ...
,
منظور کلی این است که تا زمانی که اطلاعات اون فیلد مورد نیاز نباشد Load نمی شود

مورد 5 :
وقتی که شما فقط قصد بازیابی اطلاعات را داشته باشد و نه تغیرات بر روی entity ها از Tracking استفاده می کنیم ..
در بیشتر سناریو ها Tracking به افزایش کارایی کمک خواهد کرد مخصوصا اگر شما یک توسعه دهند وب باشید . دلیل این است که entity ها در بار اول که Load می شوند در حافظه کش می شوند و در درخواست های بعدی آنها از حافظه Load می شوند // آخرش را نفهمیدم فکر ک کنم منظورش اینه که در Db های معلق از AsNoTracking استفاده نکنید


مورد 7 :
کاهش دهید میزان یا حجم کوئری ها را توسط Select کردن همه entity های متفاوت مورد نیاز برای نمایش یک صفحه در یک زمان !
برای مثال :

اگر شما نیاز دارید تا نمایش دهید اطلاعات مربوط به جدواول blogPost و author .. شما باید یک کوئری بنویسید که اطلاعات را ار جدول های author و blogPost بازیابی کند فقط با یک کوئری.. شما می تونید این کار را انجام بدهید با ترکیب کردن Projection ها و egarLoading ...

این هم یک پست خوب برای egarLoading :
http://www.entityframeworktutorial.net/EntityFramework4.3/eager-loading-with-dbcontext.aspx

ali_72
پنج شنبه 14 اسفند 1393, 09:09 صبح
ممنون دوست عزیز درباره مورد 4 و 5 منظورم این بود که کجاها نباید استفاده کنم؟

Db های معلق چیه؟
شما هم مورد 7 رو مثل 3 ترجمه کردید؟ یا من اشتباه متوجه شدم؟ تفاوت 3 و 7 چیه؟

r4hgozar
پنج شنبه 14 اسفند 1393, 10:45 صبح
سلام.
اگه منظور استفاده نکردن از لایه repostory رو زیاد قبول ندارم/‍!!

hakim22
پنج شنبه 14 اسفند 1393, 11:49 صبح
میشه به عنوان پیشنهاد به این موارد نگاه کرد. ولی هر پروژه ای نیازهای خودشو داره و همیشه کارایی در اولویت نیست.
در هر پروژه ای باید نگاه کرد به خواسته ها و شرایط و در نهایت انتخابهای مهندسی انجام داد.

aroshanzamir
پنج شنبه 14 اسفند 1393, 16:37 عصر
ممنون دوست عزیز درباره مورد 4 و 5 منظورم این بود که کجاها نباید استفاده کنم؟

Db های معلق چیه؟
شما هم مورد 7 رو مثل 3 ترجمه کردید؟ یا من اشتباه متوجه شدم؟ تفاوت 3 و 7 چیه؟



به نظر من : مورد 3 داره چیز دیگه ای را میگه : منظورش اینه که در در زمان لود اطلاعات همه فیلد ها را لود نکنیم فقط اون های را که نیاز داریم برگردونیم یا به عبارت دیگه ViewModel ها .. مثلا در یک کلاس دانشجو که شامل فیلد های Id/Name/Family/Address/Phone/ است و در زمان نمایش می خواهیم نام و نام خانوادگی را نمایش دهیم چه دلیلی وجود دارد که ما بخواهیم همه فیلد ها را لود کنیم در شرایطی که می توانیم با ایجاد یک ViewModel با فیلد های Name/Family این کار را انجام دهیم (منظورش در زمان نمایش)

ولی مورد شماره 7 داره میگه شما مثلا یک جدول باگ و یک جدول پست و یک جدول نویسنده دارید برای بارگذاری اطلاعات مثلا یک بلاگ با Id شماره 3 از select های جداگانه استفاده نکنید هر 3 را در یک کوئری بنویسید ... ممکن است کسی کسی یک select به جدول بلاگ بزند بعد یک Select به جدول پست بزند و تمام پست های را بازگشت دهد که Id بلاگ آن ها برابر با 3 باشد و بعد در جدول بلاگ که Id نویسنده هم درج شده این Id را بدست آورد و یک Select به جدول نویسنده بزند

در کل 3 تا selct زدیم در شرایطی که می تونستیم با Select این کار را انجام دهیم

برای مورد 5 نوشته فقط در زمان بازیابی اطلاعات استفاده شود

damanpak
دوشنبه 18 اسفند 1393, 00:09 صبح
سلام و شب بخیر به همه کاربران سایت برنامه نویس
سوالی داشتم در مورد بحث LazLoading و استفاده از Include
دستور زیر رو در نظر بگیرید

Dim XGetData = (From FOrder In NDataBase.Orders.Include("DetailOfOrders") Select FOrder).FirstOrDefault()
MsgBox(XGetData.DetailOfOrders.CountOfProduct)


در این مثال ما از عبارت Include استفاده کردیم
اما آیا زمانی که صراحتا از عبارت Join در دستور استفاده میکنیم بازم به Include نیاز هست؟
مثلا در مثال زیر کجا باید Include کنیم؟



Dim XGetData = (From FOrder In NDataBase.Orders Join FDetail In NDataBase.DetailOfOrders
On FOrder.ID Equals FDetail.OrderId Select FOrder).FirstOrDefault
MsgBox(XGetData.DetailOfOrders.CountOfProduct)