TKNC
13-09-2010, 06:43
با سلام ؛
بخش اول :
استفاده از LINQ to Objects در #C
بخش دوم:
ایجاد یک DataTable از یک Query
بخش سوم :
امکانات و قابلیت های LINQ برای مدیران پروژه ها
بخش چهارم :
LINQ To SQL
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
استفاده از LINQ to Objects در #C
مقدمه
این مقاله، مقدمه ایست بر استفاده از queryهای LINQ to Objects جهت ساپورت یک برنامه windows forms. این مقاله، ساختار عبارات LINQ to Objects را مورد بحث قرار می دهد و توضیح می دهد چگونه می توان از LINQ to Objects بدون بافت (context) یک برنامه واقعی استفاده کرد.
پروژه ای که در این مقاله آورده شده است، یک contact manager ساده است که ممکن است برای capture کردن و ذخیره اطلاعات مخاطب های یک شخص در قالب دفتر تلفن، مورد استفاده قرار گیرد. این برنامه از LINQ to Objects برای مدیریت، query کردن و مرتب کردن لیست مخاطبین، استفاده می کند. همچنین این برنامه شامل یک فایل contact مبتدی با مجموعه ای از مخاطبین تستی است.
شکل 1: فرم اصلی برنامه
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
این برنامه دارای عملکردهای ریز است:
یک فایل اطلاعات مخاطبین ایجاد می کند.
مخاطبین را به فایل اطلاعات مخاطبین اضافه می کند.
مخاطبین را از فایل اطلاعات مخاطبین حذف می کند.
مخاطبین را بر اساس نام خانوادگی شان جستجو می کند.
جزییات مخاطبین را ایجاد و ویرایش می کند.
نام
نام خانوادگی
خیابان
شهر
ایالت
کد پستی
تلفن منزل
تلفن محل کار
تلفن همراه
آدرس ای میل
فایل اطلاعات مخاطبین را ذخیره می کند.
فایل اطلاعات مخاطبین را دوباره باز می کند.
همه مخاطبین را در فایل اطلاعات مخاطبین پیمایش می کند.
می توان لیستی از همه مخاطبین را در فایل اطلاعات مخاطبین مشاهده کرد.
امکان جستجو را بر اساس حرف آغازین نام خانوادگی فراهم می کند (Rolodex).
معمولاً، روش های مورد استفاده در این برنامه، نمایانگر یکی از چندین روشی انجام آن کارها است، مانند خیلی از چیزها در دنیای .Net، چندین جایگزین وجود دارد و اگر مایل باشید می توانید با استفاده از جایگزین های دیگر، کد را برای کارکردن با داده ها تغییر دهید.
شکل 2: جستجوی یک مخاطب بر اساس نام خانوادگی
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
شکل 3: لیست کردن همه مخاطبین:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
شکل 4: عملکرد Rolodex
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
عبارات LINQ to Objects
این بخش، بعضی از تکنیک های رایج و مورد استفاده در ساختار عبارات LINQ to Objects را مورد بحث قرار می دهد. به طور خلاصه، LINQ to Objects، ابزاری برای مدیریت queryهایی در collectionهای درون حافظه در اختیار برنامه نویسان قرار می دهد. این تکنیک ها که برای query کردن چنین collectionهایی استفاده می شوند، شبیه روش هایی هستند که برای مدیریت queryها در databaseهای رابطه ای استفاده می شوند، ولی ساده تر هستند.
آناتومی عبارات LINQ to Objects
مثال 1: یک Select ساده
این، مثالی بسیار ساده از عبارات LINQ to Objects است:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
در این مثال، آرایه ای از رشته ها (ابزارها) به صورت collectionهایی از اشیا استفاده شده تا با استفاده از LINQ to Objects، کوئری شوند.
کوئری LINQ to Objects:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
در این مثال، یک متغیر بی نوع (untyped variable) به نام "list" ایجاد می شود و همه آیتم های موجود در string array به این این object اضافه می شوند، این typeها هر کدام دارای معنای خاصی است، مثلاً "t" بمعنای tools است؛ از آنجاییکه "tools" یک string array است، framework استنباط می کند که "t" یک string نیز هست. البته، این موضوع آنقدرها هم افتضاح نیست، زیرا شما می توانید array را تکرار کنید تا لزوماً همان کار را انجام دهید؛ اما می توانید queryهای پیچیده تری را با LINQ to Objects ایجاد کنید.
اگر قرار بود یک پروژه ایجاد کنید، این کد را به یک متد اضافه وآن را اجرا کنید، نتایج به این صورت خواهد بود:
شکل 5: query نتایج
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مثال 2: Select با یک Where Clause
این مثال، یک کوئری LINQ to Objects را نشان می دهد که شامل یک where clause می شود. در این مثال، با مجموعه ای پرنده ها به شکل یک string array شروع می کنیم؛ از LINQ to Objects برای query کردن این string array استفاده می شود تا یک subset از array را به شکل همه پرندگانی که با حرف R شروع می شوند پیدا کند و بازگرداند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اگر قرار بود این query را اجرا کنیم، نتایج به صورت زیر ظاهر می شد (همه پرندگانی که با R شروع می شوند، نشان داده شده اند):
شکل 6: نتاج کوئری پرندگان R:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مثال 3: Select با یک Where Clause
این کوئری، با اندک تفاوتی نسبت به مثال قبلی، بدنبال یک جفت دقیق در کلمه where است:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اجرای این کد منجر به نمایش پنجره زیر خواهد شد:
شکل 7: نتایج کوئری پرنده
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مثال 4: generate کردن یک Ordered List
در این کوئری، لیستی از پرندگان به ترتیب حروف الفبا مرتب شده است:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
شکل 8: نتایج کوئری Ordered Bird List
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مثال 5: کار کردن با یک type سفارشی
در این مثال، یک ایست type شده ایجاد می شود و سپس با استفاده از LINQ to Objects، کوئری می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
هدف از این مثال، تنها sort کردن لیست بخش ها به ترتیب شماره بخش ها می باشد. نتایج بازگشتی از این متد به شرح زیر است:
شکل 9: کوئری Ordered Parts List
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
کلاس parts استفاده شده در این type پشت لیست parts به شرح زیر است:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
مثال 6: جستجوی یک List<T> با استفاده از LINQ to Objects
در این مثال، یک لیست type شده ایجاد و populate می شود، و سپس با استفاده از LINQ to Objects کوئری می شود. در این مورد، کوئری شامل کلمه "where" است که فقط matchهایی را بازمیگرداند که با حرف "S" شروع می شوند"
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
شکل 10: نتایج کوئری Matching Parts
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مثال 7: جستجوی یک List<T> با استفاده از LINQ to Objects و بازگرداندن یک Single Result
در این مثال، یک لیست type شده ایجاد و populate می شود، و سپس با استفاده از LINQ to Objects کوئری می شود. در این مورد، یک single result از تایپ “Parts” را بازمی گرداند:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
ممکن است کسی از روش زیر نیز برای بازگرداندن یک single value از query استفاده کند:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
هر دو روش یک نتیجه را می دهند، همانطور که در شکل زیر نشان داده شده.
شکل 11: بازگرداندن یک Single Result
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
هدف از مثال های بالا، مروری ساده بر چگونگی مدیریت queryهای پایه ای در collectionها با استفاده از LINQ to Objects بود؛ مسلماً عملیات های پیچیده تری نیز وجود دارند که می توان با استفاده از فرآیندهای مشابه اجرا کرد.
شروع
یک solution به این مقاله الصاق شده است که شامل یک پروژه Win Forms بنام "LinqToObjects" است؛ این پروژه شامل موارد زیر است:
• دو فرم، فرم اصلی (frmContactBook) و یک فرم که برای نمایش لیست کلی مخاطبین (frmFullList) بکار می رود؛
• یک کلاس قابل serialize بنام Contact، که برای دربرگرفتن داده های مرتبط بکار می رود؛
• یک کلاس بنام Serializer که شامل دو متد استاتیک است و برای serialize و deserialize کردن داده های مخاطبین استفاده می شود.
اگر پروژه الصاق شده را در Visual Studio 2008 باز کنید، در solution explorer پنجره زیر باید ظاهر شود:
شکل 12:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
کد: Contact.cs
کلاس Contact، کلاس دربرگیرنده است که برای ذخیره همه داده های مرتبط مخاطب که در برنامه استفاده می شود، بکار می رود. در حالیکه این demonstration، از داده های مخاطب استفاده می مند، اما می توان براحتی با چیز مفیدتری جایگزین کرد.
این کلاس با importهای نرمال و پیش فرض شروع می شود:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
بخش بعدی شامل فضای نامی و تعریف کلاس می شود. توجه داشته باشید که کلاس بصورتی تعریف می شود که قابل serialize باشد، صفت قابل serialize نشان می دهد می نوان کلاس را میدهد می نوان کلاس را serialize کرد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت تعریف شده در این کلاس، عضوهای داده ای (member variables) را که درون کلاس استفاده می شوند، نشان می دهد؛ هرعضو داده ای که در درون استفاده می شود، از طریق propertyهای عمومی قابل دسترس می شوند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت بعدی کد در این کلاس شامل constructorها می شود. دو constructor تعریف می شوند، یک constructor پیش فرض که کلاس نمونه جدید ایجاد می کند و به آن یک ID داخلی تخصیص می دهد. constructor دیگر،یک ID را به عنوان پارامتر ورودی قبول می کند و ID داخلی مخاطب را به آن value اختصاص می دهد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
آخرین بخش این کد در این کلاس، شامل propertyهای قسمت (region) است، این قسمت شامل همه propertyهایی می شود که برای دسترسی به عضوهای داده ای تعریف شده اند. توجه داشته باشید که از آنجاییکه مقدار ID همیشه توسط constructor مشخص می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
کد: فرم اصلی برنامه (frmContactBook.cs)
این بخش، فرم اصلی برنامه است، قسمت بیشتر کد، قالب کاری برنامه را فراهم می کند و ربطی به LINQ to Objects ندارد، اما کل کد در اینجا توضیح داده می شود تا context مناسب را در اختیار بگذارد. فرم اصلی برنامه contact، شامل کنترل های زیر است.
Menu
File
New
Open
Save
Save As
Exit
Contacts
Add Contact
Remove Contact
List All Contacts
Toolbar
Add
Remove
Find by Last Name
Save Data
Navigate to Previous Contact
Navigate to Next Bird Contact
Exit Application
Split Container Left Hand Side
Alphabet List
Alphabetized Names List
Split Container Right Hand Side
First name text box control
Middle name text box control
Last name text box control
Street text box control
City text box control
State text box control
Zip code text box control
Home phone number text box control
Work phone number text box control
Cell number text box control
Fax number text box control
Email address text box control
شکل 13: frmContactBook.cs
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
این کلاس با importهای نرمال و پیش فرض شروع می شود:
using System;
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
بخش بعدی شامل فضای نامی و تعاریف کلاس می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمتی تعریف شده در این کلاس ، عضو داده ای را که در درون استفاده شده، تعریف می کند؛ هر عضو داده ای که در درون استفاده می شود، از طریق propertyهای عمومی، قابل دسترس می شوند. هر commentیی که کنار هر تعریف وجود دارد، منظورش را توضیح می دهد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت بعدی کد این کلاس، شامل constructor می شود. هنگام شروع، برنامه یک لیستی جدید از اطلاعات مخاطبین، و شی اطلاعات مخاطبین ایجاد می کند، و سپس نشان دهنده موقعیت کنونی را روی صفر، و فرم کثیف Boolean را روی "false " تنظیم می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت بعدی کد ‘Toolstrip Event Handlers’ نامیده می شود؛ اولین event handler در این قسمت، event handler کلیک دکمه Add است؛ این متد فقط منوی control’s click event handler را فراخوانی می کند و کد موجود در آن event handler، یک مخاطب جدید به داده های مخاطب فعلی اضافه می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
click event handler بعدی جهت خروج از برنامه، هنگامی که کاربر روی دکمه خروج toolstrip کلیک می کند، استفاده می شود؛ دوباره این handler فقط منوی click event handler را فراخوانی میکند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
click event handler بعدی، فایل اطلاعات مخاطب فعلی را را هارد ذخیره می کند، دوباره این handler فقط منوی click event handler را فراخوانی می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، مخاطب فعلی را از لیست اطلاعات مخاطبین حذف می کند؛ دوباره این handler فقط منوی click event handler را فراخوانی می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، برای جستجوی یک مخاطب براساس نام خانوادگی استفاده می شود. این کد از کوئری a LINQ to Objects استفاده می کند تا اولین نتیجه جستجو را پیدا کند. این handler از term text box control روی toolstrip استفاده می کند تا نام خانوادگی را capture کند و از دکمه search برای اجرای فرمان جستجو استفاده می کند. کد زیر برای توصیف آنچه که در این متد اتفاق می افتد، آورده شده است:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، برای بازگرداندن مخاطبی از موقعیت فعلی مخاطب نمایش داده شده استفاده می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، برای جلو بردن از موقعیت کنونی مخاطب نمایش داده شده استفاده می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت یعدی شامل منوی item click event handlers می شود. اولین menu item برای اضافه کردن مخاطبی جدید به لیست مخاظبین فعلی استفاده می شود. این متد، تابع SaveCurrentContact را فرامی خواند که هرگونه entry را که درحال حاضر به فرم ایجاد شده است را ذخیره می کند، و سپس نمون ای جدید از مخاطب ایجاد می کند، و مخاطبی جدید را به لیست مخاطبین اضافه می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
منوی بعدی item click event handler، یک لیست مخاطبین جدید ایجاد می کند؛ قبل از ایجاد لیست مخاطبین جدید، این handler چک می کند ببیند آیا فرم جاری dirty است تا به کاربر دیگر فرصت دهد قبل از اینکه لیست جاری را ببندد، آن را ذخیره کند. با پیروی از آن، لیست مخاطبین با لیستی جدید جایگزین می شود و کنترل های فرم پاک می شوند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، برای بازکردن فایل مخاطب بکار می رود. این handler، یک فرو dirty را چک می کند و اگر فرم dirty باشد، فرصت ذخیره کردن را به کاربر میب دهد. یک متد open مجزا فراخوانی می شود تا عملیات واقعی باز کردن فایل را handle کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، بعد از اینکه دوباره چک کرد آیا فرم dirty است یا خیر، برنامه را می بنند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
save menu item برای ذخیره فایل مخاطبین فعلی روی هارد بکار می رود؛ این تابع ابتدا یک SaveCurrentContact را فرامی خواند که برای ذخیره مخاطب فعلی در لیست اطلاعات مخاطبین جاری استفاده می شود. و اگر در حال حاضر هیچ نامی برای متغیر currentFilePath تعیین نشده باشد، این تابع از پنجره save file برای capture کردن نام یک فایل استفاده می کند، یا، اگر متغیر تعیین شده باشد، فایل را با استفاده از مسیر فایل ذخیره می کند. این فایل هنگام فراخوانی فایل serialize کردن، روی هارد ذخیره می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت بعدی کد جهت ساپورت آیتم منوی “Save As” بکار می رود، متد فراخوانی، شبیه متد قبلی save است، ولی مستقیماً پنجره Save File را باز می کند تا به کاربر اجازه نامگذاری فایل یا تغییر نام فایل را بدهد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
متد بعدی، مخاطب فعلی را از لیست مخاطبین حذف می کند و موقعیت مخاطب فعلی را آپدیت می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
متد بعدی برای برای مرتب کردن مخاطبین بر اساس حروف الفبا و ارسال لیست نتایج به نمونه ای از فرم که برای نمایش همه مخاطبین موجود در data grid view control بکار می رود، استفاده می شود. لیست مخاطبین فعلی بر اساس حروف الفبای نام خانوادگی، نام میانی، و نام کوچک مرتب می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت بعدی شامل یک garbage can collection از متدهایی است که در قسمتی بنام “Housekeeping” نگهداری می شود:
#region Housekeeping
اولین متدی موجود در این بخش برای پاک کردن همه text box هایی استفاده می شود که برای نمایش اطلاعات مخاطب بکار می رود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
از متد بعدی برای بارگذاری اطلاعات موجود در مخاطب فعلی به کنترل هایی استفاده می شود که برای نمایش اطلاعات مخاطب بکار می رود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
متد بعدی تمامی اطلاعاتی را که در حال حاضر روی فرم مخاطب فعلی قرار دارد capture می کند و آن را روی propertyهای مخاطب فعلی می نویسد. هرگاه یک مخاطب اغییر پیدا می کند، بطوری که همه ویرایش ها روی مخاطب موجود در لیست local باقی می ماند تا روی هارد نوشته شود، این متد فراخوانی می شود. بعلاوه، این متد ترتیب و لیست مخاطبین و مخاطب نمایش داده شده را update می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
از متد بعدی برای باز کردن و deserialize کردن فایل مخاطب موجود استفاده می شود، وآن را برای ویرایش و مشاهده از درون برنامه آماده می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت آخر در این کلاس فرم برای handle کردن eventهای کنترل listbox استفاده می شود. این کنترل ها برای فراهم کردن یک Rolodex از عملکردهای برنامه بکار می رود. کنترل های listbox در سمت چپ کترل پنل split بارگذاری می شوند. کنترل listbox تمامی حروف الفبا را، هنگامی که از کنترل listbox پایینی برای نمایش همه نام های خانوادگی که با حرفی که در listbox بالایی انتخاب شده استفاده می شود، نشان می دهد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
تابع اول، index انتخابی برای listbox بالایی که حاوی همه حروف الفبا است را handle می کند. وقتی یک حرف جدید انتخاب می شود، این متد از یک query ساده LINQ to Objects برای پیدا کردن همه مخاطبین با نام خانوادگی ای که با حرف انتخای شده شروع می شوند، استفاده می کند. سپس listbox پایینی پاک می شود و سپس مخاطبین یافته شده در یک string که نام خانوادگی، نام کوچک و نام میانی مخاطب را نشان می دهد، نمایش داده می شوند، و هر string نمایش داد ه شده به کنترل listbox پایینی اضافه می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
رویداد selected index changed از لیست باکس names، در قسمت بعدی کد handle می شود. در آن، string نام (که نام خانوادگی، نام کوچک و نام میانی) parse می شود و در کوئری LINQ to Objects استفاده می شود تا لیستی از همه نام های پیدا شده را بازگرداند؛ اولین نام پیدا شده در فرم مخاطب نمایش داده می شود و موقعیت index برای ساپورت پیمایش لیست update می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
کد: frmFullList.cs
کلاس فرم حاوی یک کنترل data grid view و یک constructor است که لیست مخاطب را به صورت پارامتر ورودی (argument) قبول می کند. هنگام شروع، لیست به کنترل data grid view محدود می شود. تغییرات اعمال شده توسط ویرایش ها در grid، در لیست مخاطبین نگهداری می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
خلاصه مقاله
این مقاله تعدادی مثال ساده از کوئری های LINQ to Objects را نشان می دهد که در ساپورت یک برنامه ساده بکار می رود. ممکن است از LINQ to Objects برای generate کردن کوئری های پیچیده تری استفاده شود، اما کوئری هایی که در این مقاله نشان داده شدند، نشانگر بعضی از taskهای رایجی است که ممکن است در برنامه ای مشابه انجام شوند. اکثر کدها به صورت قالب کاری برای برنامه در اختیار شما قرار داده شدند، و برای ایجاد محیطی مفید برای تست کردن بعضی از کوئری های وابسته به LINQ to Objects ضروری بودند.
بخش اول :
استفاده از LINQ to Objects در #C
بخش دوم:
ایجاد یک DataTable از یک Query
بخش سوم :
امکانات و قابلیت های LINQ برای مدیران پروژه ها
بخش چهارم :
LINQ To SQL
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
استفاده از LINQ to Objects در #C
مقدمه
این مقاله، مقدمه ایست بر استفاده از queryهای LINQ to Objects جهت ساپورت یک برنامه windows forms. این مقاله، ساختار عبارات LINQ to Objects را مورد بحث قرار می دهد و توضیح می دهد چگونه می توان از LINQ to Objects بدون بافت (context) یک برنامه واقعی استفاده کرد.
پروژه ای که در این مقاله آورده شده است، یک contact manager ساده است که ممکن است برای capture کردن و ذخیره اطلاعات مخاطب های یک شخص در قالب دفتر تلفن، مورد استفاده قرار گیرد. این برنامه از LINQ to Objects برای مدیریت، query کردن و مرتب کردن لیست مخاطبین، استفاده می کند. همچنین این برنامه شامل یک فایل contact مبتدی با مجموعه ای از مخاطبین تستی است.
شکل 1: فرم اصلی برنامه
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
این برنامه دارای عملکردهای ریز است:
یک فایل اطلاعات مخاطبین ایجاد می کند.
مخاطبین را به فایل اطلاعات مخاطبین اضافه می کند.
مخاطبین را از فایل اطلاعات مخاطبین حذف می کند.
مخاطبین را بر اساس نام خانوادگی شان جستجو می کند.
جزییات مخاطبین را ایجاد و ویرایش می کند.
نام
نام خانوادگی
خیابان
شهر
ایالت
کد پستی
تلفن منزل
تلفن محل کار
تلفن همراه
آدرس ای میل
فایل اطلاعات مخاطبین را ذخیره می کند.
فایل اطلاعات مخاطبین را دوباره باز می کند.
همه مخاطبین را در فایل اطلاعات مخاطبین پیمایش می کند.
می توان لیستی از همه مخاطبین را در فایل اطلاعات مخاطبین مشاهده کرد.
امکان جستجو را بر اساس حرف آغازین نام خانوادگی فراهم می کند (Rolodex).
معمولاً، روش های مورد استفاده در این برنامه، نمایانگر یکی از چندین روشی انجام آن کارها است، مانند خیلی از چیزها در دنیای .Net، چندین جایگزین وجود دارد و اگر مایل باشید می توانید با استفاده از جایگزین های دیگر، کد را برای کارکردن با داده ها تغییر دهید.
شکل 2: جستجوی یک مخاطب بر اساس نام خانوادگی
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
شکل 3: لیست کردن همه مخاطبین:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
شکل 4: عملکرد Rolodex
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
عبارات LINQ to Objects
این بخش، بعضی از تکنیک های رایج و مورد استفاده در ساختار عبارات LINQ to Objects را مورد بحث قرار می دهد. به طور خلاصه، LINQ to Objects، ابزاری برای مدیریت queryهایی در collectionهای درون حافظه در اختیار برنامه نویسان قرار می دهد. این تکنیک ها که برای query کردن چنین collectionهایی استفاده می شوند، شبیه روش هایی هستند که برای مدیریت queryها در databaseهای رابطه ای استفاده می شوند، ولی ساده تر هستند.
آناتومی عبارات LINQ to Objects
مثال 1: یک Select ساده
این، مثالی بسیار ساده از عبارات LINQ to Objects است:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
در این مثال، آرایه ای از رشته ها (ابزارها) به صورت collectionهایی از اشیا استفاده شده تا با استفاده از LINQ to Objects، کوئری شوند.
کوئری LINQ to Objects:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
در این مثال، یک متغیر بی نوع (untyped variable) به نام "list" ایجاد می شود و همه آیتم های موجود در string array به این این object اضافه می شوند، این typeها هر کدام دارای معنای خاصی است، مثلاً "t" بمعنای tools است؛ از آنجاییکه "tools" یک string array است، framework استنباط می کند که "t" یک string نیز هست. البته، این موضوع آنقدرها هم افتضاح نیست، زیرا شما می توانید array را تکرار کنید تا لزوماً همان کار را انجام دهید؛ اما می توانید queryهای پیچیده تری را با LINQ to Objects ایجاد کنید.
اگر قرار بود یک پروژه ایجاد کنید، این کد را به یک متد اضافه وآن را اجرا کنید، نتایج به این صورت خواهد بود:
شکل 5: query نتایج
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مثال 2: Select با یک Where Clause
این مثال، یک کوئری LINQ to Objects را نشان می دهد که شامل یک where clause می شود. در این مثال، با مجموعه ای پرنده ها به شکل یک string array شروع می کنیم؛ از LINQ to Objects برای query کردن این string array استفاده می شود تا یک subset از array را به شکل همه پرندگانی که با حرف R شروع می شوند پیدا کند و بازگرداند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اگر قرار بود این query را اجرا کنیم، نتایج به صورت زیر ظاهر می شد (همه پرندگانی که با R شروع می شوند، نشان داده شده اند):
شکل 6: نتاج کوئری پرندگان R:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مثال 3: Select با یک Where Clause
این کوئری، با اندک تفاوتی نسبت به مثال قبلی، بدنبال یک جفت دقیق در کلمه where است:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اجرای این کد منجر به نمایش پنجره زیر خواهد شد:
شکل 7: نتایج کوئری پرنده
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مثال 4: generate کردن یک Ordered List
در این کوئری، لیستی از پرندگان به ترتیب حروف الفبا مرتب شده است:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
شکل 8: نتایج کوئری Ordered Bird List
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مثال 5: کار کردن با یک type سفارشی
در این مثال، یک ایست type شده ایجاد می شود و سپس با استفاده از LINQ to Objects، کوئری می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
هدف از این مثال، تنها sort کردن لیست بخش ها به ترتیب شماره بخش ها می باشد. نتایج بازگشتی از این متد به شرح زیر است:
شکل 9: کوئری Ordered Parts List
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
کلاس parts استفاده شده در این type پشت لیست parts به شرح زیر است:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
مثال 6: جستجوی یک List<T> با استفاده از LINQ to Objects
در این مثال، یک لیست type شده ایجاد و populate می شود، و سپس با استفاده از LINQ to Objects کوئری می شود. در این مورد، کوئری شامل کلمه "where" است که فقط matchهایی را بازمیگرداند که با حرف "S" شروع می شوند"
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
شکل 10: نتایج کوئری Matching Parts
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
مثال 7: جستجوی یک List<T> با استفاده از LINQ to Objects و بازگرداندن یک Single Result
در این مثال، یک لیست type شده ایجاد و populate می شود، و سپس با استفاده از LINQ to Objects کوئری می شود. در این مورد، یک single result از تایپ “Parts” را بازمی گرداند:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
ممکن است کسی از روش زیر نیز برای بازگرداندن یک single value از query استفاده کند:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
هر دو روش یک نتیجه را می دهند، همانطور که در شکل زیر نشان داده شده.
شکل 11: بازگرداندن یک Single Result
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
هدف از مثال های بالا، مروری ساده بر چگونگی مدیریت queryهای پایه ای در collectionها با استفاده از LINQ to Objects بود؛ مسلماً عملیات های پیچیده تری نیز وجود دارند که می توان با استفاده از فرآیندهای مشابه اجرا کرد.
شروع
یک solution به این مقاله الصاق شده است که شامل یک پروژه Win Forms بنام "LinqToObjects" است؛ این پروژه شامل موارد زیر است:
• دو فرم، فرم اصلی (frmContactBook) و یک فرم که برای نمایش لیست کلی مخاطبین (frmFullList) بکار می رود؛
• یک کلاس قابل serialize بنام Contact، که برای دربرگرفتن داده های مرتبط بکار می رود؛
• یک کلاس بنام Serializer که شامل دو متد استاتیک است و برای serialize و deserialize کردن داده های مخاطبین استفاده می شود.
اگر پروژه الصاق شده را در Visual Studio 2008 باز کنید، در solution explorer پنجره زیر باید ظاهر شود:
شکل 12:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
کد: Contact.cs
کلاس Contact، کلاس دربرگیرنده است که برای ذخیره همه داده های مرتبط مخاطب که در برنامه استفاده می شود، بکار می رود. در حالیکه این demonstration، از داده های مخاطب استفاده می مند، اما می توان براحتی با چیز مفیدتری جایگزین کرد.
این کلاس با importهای نرمال و پیش فرض شروع می شود:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
بخش بعدی شامل فضای نامی و تعریف کلاس می شود. توجه داشته باشید که کلاس بصورتی تعریف می شود که قابل serialize باشد، صفت قابل serialize نشان می دهد می نوان کلاس را میدهد می نوان کلاس را serialize کرد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت تعریف شده در این کلاس، عضوهای داده ای (member variables) را که درون کلاس استفاده می شوند، نشان می دهد؛ هرعضو داده ای که در درون استفاده می شود، از طریق propertyهای عمومی قابل دسترس می شوند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت بعدی کد در این کلاس شامل constructorها می شود. دو constructor تعریف می شوند، یک constructor پیش فرض که کلاس نمونه جدید ایجاد می کند و به آن یک ID داخلی تخصیص می دهد. constructor دیگر،یک ID را به عنوان پارامتر ورودی قبول می کند و ID داخلی مخاطب را به آن value اختصاص می دهد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
آخرین بخش این کد در این کلاس، شامل propertyهای قسمت (region) است، این قسمت شامل همه propertyهایی می شود که برای دسترسی به عضوهای داده ای تعریف شده اند. توجه داشته باشید که از آنجاییکه مقدار ID همیشه توسط constructor مشخص می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
کد: فرم اصلی برنامه (frmContactBook.cs)
این بخش، فرم اصلی برنامه است، قسمت بیشتر کد، قالب کاری برنامه را فراهم می کند و ربطی به LINQ to Objects ندارد، اما کل کد در اینجا توضیح داده می شود تا context مناسب را در اختیار بگذارد. فرم اصلی برنامه contact، شامل کنترل های زیر است.
Menu
File
New
Open
Save
Save As
Exit
Contacts
Add Contact
Remove Contact
List All Contacts
Toolbar
Add
Remove
Find by Last Name
Save Data
Navigate to Previous Contact
Navigate to Next Bird Contact
Exit Application
Split Container Left Hand Side
Alphabet List
Alphabetized Names List
Split Container Right Hand Side
First name text box control
Middle name text box control
Last name text box control
Street text box control
City text box control
State text box control
Zip code text box control
Home phone number text box control
Work phone number text box control
Cell number text box control
Fax number text box control
Email address text box control
شکل 13: frmContactBook.cs
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
این کلاس با importهای نرمال و پیش فرض شروع می شود:
using System;
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
بخش بعدی شامل فضای نامی و تعاریف کلاس می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمتی تعریف شده در این کلاس ، عضو داده ای را که در درون استفاده شده، تعریف می کند؛ هر عضو داده ای که در درون استفاده می شود، از طریق propertyهای عمومی، قابل دسترس می شوند. هر commentیی که کنار هر تعریف وجود دارد، منظورش را توضیح می دهد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت بعدی کد این کلاس، شامل constructor می شود. هنگام شروع، برنامه یک لیستی جدید از اطلاعات مخاطبین، و شی اطلاعات مخاطبین ایجاد می کند، و سپس نشان دهنده موقعیت کنونی را روی صفر، و فرم کثیف Boolean را روی "false " تنظیم می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت بعدی کد ‘Toolstrip Event Handlers’ نامیده می شود؛ اولین event handler در این قسمت، event handler کلیک دکمه Add است؛ این متد فقط منوی control’s click event handler را فراخوانی می کند و کد موجود در آن event handler، یک مخاطب جدید به داده های مخاطب فعلی اضافه می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
click event handler بعدی جهت خروج از برنامه، هنگامی که کاربر روی دکمه خروج toolstrip کلیک می کند، استفاده می شود؛ دوباره این handler فقط منوی click event handler را فراخوانی میکند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
click event handler بعدی، فایل اطلاعات مخاطب فعلی را را هارد ذخیره می کند، دوباره این handler فقط منوی click event handler را فراخوانی می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، مخاطب فعلی را از لیست اطلاعات مخاطبین حذف می کند؛ دوباره این handler فقط منوی click event handler را فراخوانی می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، برای جستجوی یک مخاطب براساس نام خانوادگی استفاده می شود. این کد از کوئری a LINQ to Objects استفاده می کند تا اولین نتیجه جستجو را پیدا کند. این handler از term text box control روی toolstrip استفاده می کند تا نام خانوادگی را capture کند و از دکمه search برای اجرای فرمان جستجو استفاده می کند. کد زیر برای توصیف آنچه که در این متد اتفاق می افتد، آورده شده است:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، برای بازگرداندن مخاطبی از موقعیت فعلی مخاطب نمایش داده شده استفاده می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، برای جلو بردن از موقعیت کنونی مخاطب نمایش داده شده استفاده می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت یعدی شامل منوی item click event handlers می شود. اولین menu item برای اضافه کردن مخاطبی جدید به لیست مخاظبین فعلی استفاده می شود. این متد، تابع SaveCurrentContact را فرامی خواند که هرگونه entry را که درحال حاضر به فرم ایجاد شده است را ذخیره می کند، و سپس نمون ای جدید از مخاطب ایجاد می کند، و مخاطبی جدید را به لیست مخاطبین اضافه می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
منوی بعدی item click event handler، یک لیست مخاطبین جدید ایجاد می کند؛ قبل از ایجاد لیست مخاطبین جدید، این handler چک می کند ببیند آیا فرم جاری dirty است تا به کاربر دیگر فرصت دهد قبل از اینکه لیست جاری را ببندد، آن را ذخیره کند. با پیروی از آن، لیست مخاطبین با لیستی جدید جایگزین می شود و کنترل های فرم پاک می شوند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، برای بازکردن فایل مخاطب بکار می رود. این handler، یک فرو dirty را چک می کند و اگر فرم dirty باشد، فرصت ذخیره کردن را به کاربر میب دهد. یک متد open مجزا فراخوانی می شود تا عملیات واقعی باز کردن فایل را handle کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
handler بعدی، بعد از اینکه دوباره چک کرد آیا فرم dirty است یا خیر، برنامه را می بنند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
save menu item برای ذخیره فایل مخاطبین فعلی روی هارد بکار می رود؛ این تابع ابتدا یک SaveCurrentContact را فرامی خواند که برای ذخیره مخاطب فعلی در لیست اطلاعات مخاطبین جاری استفاده می شود. و اگر در حال حاضر هیچ نامی برای متغیر currentFilePath تعیین نشده باشد، این تابع از پنجره save file برای capture کردن نام یک فایل استفاده می کند، یا، اگر متغیر تعیین شده باشد، فایل را با استفاده از مسیر فایل ذخیره می کند. این فایل هنگام فراخوانی فایل serialize کردن، روی هارد ذخیره می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت بعدی کد جهت ساپورت آیتم منوی “Save As” بکار می رود، متد فراخوانی، شبیه متد قبلی save است، ولی مستقیماً پنجره Save File را باز می کند تا به کاربر اجازه نامگذاری فایل یا تغییر نام فایل را بدهد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
متد بعدی، مخاطب فعلی را از لیست مخاطبین حذف می کند و موقعیت مخاطب فعلی را آپدیت می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
متد بعدی برای برای مرتب کردن مخاطبین بر اساس حروف الفبا و ارسال لیست نتایج به نمونه ای از فرم که برای نمایش همه مخاطبین موجود در data grid view control بکار می رود، استفاده می شود. لیست مخاطبین فعلی بر اساس حروف الفبای نام خانوادگی، نام میانی، و نام کوچک مرتب می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت بعدی شامل یک garbage can collection از متدهایی است که در قسمتی بنام “Housekeeping” نگهداری می شود:
#region Housekeeping
اولین متدی موجود در این بخش برای پاک کردن همه text box هایی استفاده می شود که برای نمایش اطلاعات مخاطب بکار می رود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
از متد بعدی برای بارگذاری اطلاعات موجود در مخاطب فعلی به کنترل هایی استفاده می شود که برای نمایش اطلاعات مخاطب بکار می رود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
متد بعدی تمامی اطلاعاتی را که در حال حاضر روی فرم مخاطب فعلی قرار دارد capture می کند و آن را روی propertyهای مخاطب فعلی می نویسد. هرگاه یک مخاطب اغییر پیدا می کند، بطوری که همه ویرایش ها روی مخاطب موجود در لیست local باقی می ماند تا روی هارد نوشته شود، این متد فراخوانی می شود. بعلاوه، این متد ترتیب و لیست مخاطبین و مخاطب نمایش داده شده را update می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
از متد بعدی برای باز کردن و deserialize کردن فایل مخاطب موجود استفاده می شود، وآن را برای ویرایش و مشاهده از درون برنامه آماده می کند.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
قسمت آخر در این کلاس فرم برای handle کردن eventهای کنترل listbox استفاده می شود. این کنترل ها برای فراهم کردن یک Rolodex از عملکردهای برنامه بکار می رود. کنترل های listbox در سمت چپ کترل پنل split بارگذاری می شوند. کنترل listbox تمامی حروف الفبا را، هنگامی که از کنترل listbox پایینی برای نمایش همه نام های خانوادگی که با حرفی که در listbox بالایی انتخاب شده استفاده می شود، نشان می دهد.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
تابع اول، index انتخابی برای listbox بالایی که حاوی همه حروف الفبا است را handle می کند. وقتی یک حرف جدید انتخاب می شود، این متد از یک query ساده LINQ to Objects برای پیدا کردن همه مخاطبین با نام خانوادگی ای که با حرف انتخای شده شروع می شوند، استفاده می کند. سپس listbox پایینی پاک می شود و سپس مخاطبین یافته شده در یک string که نام خانوادگی، نام کوچک و نام میانی مخاطب را نشان می دهد، نمایش داده می شوند، و هر string نمایش داد ه شده به کنترل listbox پایینی اضافه می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
رویداد selected index changed از لیست باکس names، در قسمت بعدی کد handle می شود. در آن، string نام (که نام خانوادگی، نام کوچک و نام میانی) parse می شود و در کوئری LINQ to Objects استفاده می شود تا لیستی از همه نام های پیدا شده را بازگرداند؛ اولین نام پیدا شده در فرم مخاطب نمایش داده می شود و موقعیت index برای ساپورت پیمایش لیست update می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
کد: frmFullList.cs
کلاس فرم حاوی یک کنترل data grid view و یک constructor است که لیست مخاطب را به صورت پارامتر ورودی (argument) قبول می کند. هنگام شروع، لیست به کنترل data grid view محدود می شود. تغییرات اعمال شده توسط ویرایش ها در grid، در لیست مخاطبین نگهداری می شود.
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
خلاصه مقاله
این مقاله تعدادی مثال ساده از کوئری های LINQ to Objects را نشان می دهد که در ساپورت یک برنامه ساده بکار می رود. ممکن است از LINQ to Objects برای generate کردن کوئری های پیچیده تری استفاده شود، اما کوئری هایی که در این مقاله نشان داده شدند، نشانگر بعضی از taskهای رایجی است که ممکن است در برنامه ای مشابه انجام شوند. اکثر کدها به صورت قالب کاری برای برنامه در اختیار شما قرار داده شدند، و برای ایجاد محیطی مفید برای تست کردن بعضی از کوئری های وابسته به LINQ to Objects ضروری بودند.