استفاده از IEnumerable و IQueryable در #C

در این مطلب به بررسی IEnumerable و IQueryable در سی شارپ پرداختیم ویژگی هر یک و چه زمانی باید از IEnumerable و IQueryable استفاده کنیم.ما در این مطلب نیز به بررسی با موضوع چه زمانی از IEnumerable ، ICollection، IList و List استفاده کنیم؟ دیگر ویژگی ها را بررسی کردیم.

یک برنامه نویس #C همیشه در استفاده از رابط های زیر دچار سردرگمی می شود:

IEnumerable
IQueryable
ICollection
IList

با توجه به اینکه سردرگمی برنامه نویسان در استفاده از رابط های بالا را مشاهده کردم تصمیم دارم در این مقاله، تفاوت های اصلی بین IEnumerable<T> و IQueryable<T> و همین طور موارد استفاده هرکدام را توضیح دهم.

IEnumerable<T>

IEnumerable<T> برای حلقه تکرار زدن روی یک مجموعه فقط خواندنی است (read only collection)، که تنها یک متد GetEnumeartor() دارد که این امکان را فراهم می کند با استفاده از حلقه ی foreach مجموعه های read only collection را تکرارکند. تکرار فقط در جهت جلو امکان پذیر است. IEnumerable <T> به صورت زیر تعریف می شود:

همان طور که مشاهده می کنید این تعریف شامل هیچ تابع دیگری مثل add,remove,count و غیره نیست. پس نمی توانید اشیا را در IEnumerable collection جمع یا حذف کنید بلکه فقط یک مجموعه فقط خواندنی است و حتی برای پیدا کردن شماره هر شی در مجموعه، باید روی کل مجموعه عمل حلقه تکرار بزنید. از مهم ترین نکات مربوط به IEnumerable<T> در ادامه مطرح خواهد شد:

یک مجوعه فقط خواندنی است
تکرار فقط در جهت جلو(مستقیم) صورت می گیرد.
اعمال جمع یا حذف روی objects امکان پذیر نیست.
برای تکرار در مجموعه (در جهت مستقیم)، enumerator فراهم شده است.

یک رابط پایه است برای هرنوع مجموعه ای که با استفاده از دستور foreach قابل شمارش(enumerate) است. برای انجام عمل تکرار از یک foreach استفاده می کنیم و یک مجموعه عمومی باید IEnumerable <T> را پیاده سازی کرده و متد GetEnumerator() را تعریف کند.

IQueryable

متد GetEnumerator() ریسمان(thread) امنی نیست. Enumerator برای خواندن مجموعه ها از موقعیت یابی استفاده کرده و در اولین موقعیت در یک مجموعه قرار می گیرد. برای خواندن اشیا بعدی در مجموعه . باید متد MoveNext() را فراخوانی کنید.

چه زمانی از IEnumerable<T> استفاده کنیم؟

به سوالات زیر پاسخ دهید:

آیا می خواهید با مجموعه های read only collection کار کنید؟

آیا نیاز به خواندن Objects(در جهت فقط پیشرو) دارید؟

نسبت به امنیت ریسمان ها نگران نیستید؟

آیا می خواهید با استفاده از foreach روی مجموعه های اشیا عمل تکرار را انجام دهید؟

اگر تنها به یکی از سوال های بالا پاسخ مثبت دادید پس به نحوه استفاده از IEnumerable <T> در ادامه توجه کنید:

IQueryable<T>

طبق مستندات MSDN ، IQueryable<T> اجازه می دهد تا روی یک منبع داده ای مشخص،که نوع داده های آن مشخص نیست، یک پرس و جو اجرا کنید.

IQueryable به صورت زیر تعریف می شود:

IQueryable<T> ،IEnumerable را توسعه داده و در نتیجه به شما اجازه می دهد تا عمل تکرار روی یک مجموعه را با استفاده از دستور foreach انجام دهید. تمامی مشخصات یک IQueryable فقط خواندنی است.

IQueryable<T> ، IQueryable و IEnumerable را توسعه داده و به صورت زیر تعریف می شود:

برای واکشی یک رکورد از یک پایگاه داده( از راه دور) باید از IQueryable<T> استفاده کنید. IQueryable پرس و جو را با استفاده از درخت عبارت ها(Expression Tree) شکل می دهد. به عبارت دیگر در IEnumerable <T> پرس و جو با استفاده از delegate ایجاد می شود. با استفاده از IQueryable<T> و IEnumerable <T> به راحتی می توان از سرور های پایگاه داده، داده ها را بارگذاری کرد.

وقت آن رسیده تا از IEnumerable <T> یا IQueryable<T> استفاده کنیم اجازه دهید تا SQL تولید شده برای LINQ زیر را به نمایش بگذاریم:

 

SQL تولید شده به صورت زیر خواهد بود:

همان طور که دقت می کنید اگرچه با استفاده از عملگر where روی پرس و جویمان، فیلتر اعمال کردیم، IEnumerable<T> همه ی داده ها را از جدول پایگاه داده مان واکشی کرده و فیلتر را روی تمامی داده های بازگشتی در حافظه، اعمال کرده است.

به عبارت بهتر، اجازه دهید تا پرس و جوی قبلی را با استفاده از IQueryable<T> بازنویسی کنیم و پرس و جوی SQL تولید شده را امتحان کنیم:
C#

 

SQL تولید شده به صورت زیر خواهد بود:

همانطور که متوجه هستید، پرس و جوی تولید شده یک عبارت where داشته و به وسیله ی LINQ to SQL، تنها داده های فیلتر شده از پایگاه داده واکشی می شوند. اگر از IQueryable و foreach استفاده می کنید، پرس و جو در زمان یکسانی محاسبه و اجرا می شود.

حالا نوبت به بررسی مهم ترین نکات مربوط به IQueryable<T> است:

IEnumerable <T> را پیاده سازی می کند پس با استفاده از foreach می توان روی نتایج عمل تکرار را انجام دهیم.
بهترین روش برای پرس و جو زدن در منابع داده ای خارجی هستند(external data sources).
با استفاده از درخت عبارت ها، پرس و جو را ایجاد می کند.
برای پرس و جو زدن روی منابع داده ای قابل پرس و جو(queryable) استفاده می شوند.

وقتی از IQueryable<T> استفاده می کنید پرس و جو با استفاده از درخت عبارت ایجاد می شود و یک قدم جلوتر از سرویس دهنده LINQ برداشته و درخت عبارت را به پرس و جو واقعی تبدیل می کند. همیشه به خاطر داشته باشید که IQueryable<T> فقط پرس و جو را ساخته و داده ها را از روش غیر مستقیم بارگذاری می کند.

چه زمانی از IQueryable<T> استفاده کنیم؟

به سوالات زیر پاسخ دهید:

آیا می خواهید با با منابع داده ای قابل پرس و جو زدن، کار کنید؟
آیا می خواهید روی داده های موجود در منابع تان فیلتر اعمال کنید؟
می خواهید صفحه بندی(paging) و ترکیب(composition) انجام دهید؟
با منابع داده ای خارجی کار می کنید؟
می خواهید داده ها را به روش غیر مستقیم بارگذاری کنید؟
می خواهید با استفاد از foreach روی مجموعه عمل تکرار را انجام دهید؟

اگر تنها به یکی از سوال های بالا پاسخ مثبت دادید پس به نحوه استفاده از IQueryable<T> در ادامه توجه کنید:

هنگام استفاده از مواظب باشید IQueryable کپسول سازی(encapsulation) مخزن تان(repository) از بین نرود، نگرانید که برخی داده های مشخص از مخزنتان برای بقیه کدهایتان آشکار باشد.

اگر واقعا می خواهید از یک مخزن استفاده کنید البته با اعمال فیلتر؛ باید موارد زیر را رعایت کنید:

اضافه کردن متدهای پرس و جوی اضافی یا فرستادن یک مشخصه یا یک گزاره(خبر) به یکی از متدهای لیست مخازن(همچنان IEnumerable را برمی گرداند)

خلاصه:

IEnumerable <T> با مجموعه های در حافظه محلی کار می کنند برخلاف IQueryable<T> که با پایگاه دادهکار می کند. اگر با LINQ to SQL کار می کنید بهترین راه استفاده از IEnumerable <T> است البته تا زمانی که خبری از live data نباشد یا بخواهید از کلاس DataConext توابع فراخوانی(call functions) را حذف یا اضافه کنید.

IQueryable<T> لیستی از خودش را بر نمی گرداند و ترجیحا پرس و جو را خودش می سازد. برای برگرداندن لیست از IQueryable<T> باید از AsQueryable استفاده کنید.

 

استفاده از IEnumerable و IQueryable در #C
5 (100%) 1 رای

(434 نوشته)

C# Programmer , Web Design And Developer , MVC , ASP.NET

فکر شما چیست؟

آدرس ایمیل شما منتشر نخواهد شد. بخشهای موردنیاز علامتگذاری شدهاند *

حاصل جمع اعداد را وارد کنید : *