ورود

نسخه کامل مشاهده نسخه کامل : LINQ



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 ضروری بودند.

TKNC
15-09-2010, 15:25
بخش دوم
ایجاد یک DataTable از یک
Data binding، یکی از کاربردهای رایج شی DataTable است. متد CopyToDataTable، خروجی های یک query را می گیرد و داده ها را در DataTable کپی می کند، و سپس می توان برای data binding استفاده کرد. وقتی عملیات های داده ها اجرا شود، DataTable جدید دوباره با DataTable منبع ادغام می شود.


متد CopyToDataTable از فرآیند زیر برای ایجاد یک DataTable از یک query استفاده می مند.

متد CopyToDataTable، یک DataTable را از منبع جدول کپی برداری می کند (یک شی DataTable که اینترفیس IQueryable<T> را پیاده سازی می کند). منبع IEnumerable عموماً از یک عبارت LINQ to DataSet یا query متد نشات می گیرد.
Schemaی DataTable کپی برداری شده، از ستون های شی DataRow شمارش شده در جدول منبع ساخته می شود، و نام جدول کپی برداری شده، نام جدول منبع است که کلمه "query" به آن ضمیمه شده است.
برای هر ردیف در جدول منبع، محتویات ردیف به یک شی DataRow جدید کپی می شود، و سپس به جدول کپی برداری شده، وارد می شود. Propertyهای RowState و RowError، در طول عملیات کپی کردن، بدون تغییر باقی می مانند. اگر اشیاء DataRow در منبع از جدولی دیگر باشند، یک ArgumentException، ایجاد می شود.
بعد از اینکه همه اشیاء DataRow در جدول خروجی قابل query کپی شوند، DataTable کپی شده بازگردانده می شود. اگر sequence اصلی، حاوی هیچ شی DataRow نباشد، متد یک DataTable خالی بازمی گرداند.
توجه داشته باشید که فراخوانی متد CopyToDataTable، باعث خواهد شد query برای اجرا شدن به جدول منبع بچسبد.
وقتی که متد CopyToDataTable با یک مرجع null یا value type قابل null در یک ردیف در جدول منبع روبرو می شود، . در این روش، valueهای null، در DataTable بازگردانده شده، بدرستی مدیریت می شوند.
نکته: متد CopyToDataTable، به صورت یک خروجی که می تواند ردیف ها را از اشیاء DataTable یا DataSet بازگرداند، پذیرفته می شود. متد CopyToDataTable، داده ها را کپی می کند، اما propertyها را از اشیاء DataTable یا DataSet اصلی به DataTable بازگردانده شده کپی نمی کند. شما باید propertyها، از قبیل Locale و TableName را در DataTable بازگردانده شده مستقیماً تنظیم کنید.
مثال زیر، جدول SalesOrderHeader table را برای سفارش های بعد 8 آگوست 2001، query می کند، و از متد CopyToDataTable برای ایجاد یک DataTable از آن query استفاده می کند. سپس DataTable به یک BindingSource می چسبد که به عنوان یک ------ برای یک DataGridView عمل می کند.

---------------------------------------------------------------------------------------------------------------------------------------------------------------
در VB:

' Bind the System.Windows.Forms.DataGridView object
' to the System.Windows.Forms.BindingSource object.
dataGridView.DataSource = bindingSource

' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim orders As DataTable = ds.Tables("SalesOrderHeader")

' Query the SalesOrderHeader table for orders placed
' after August 8, 2001.
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of DateTime)("OrderDate") > New DateTime(2001, 8, 1) _
Select order

' Create a table from the query.
Dim boundTable As DataTable = query.CopyToDataTable()

' Bind the table to a System.Windows.Forms.BindingSource object,
' which acts as a proxy for a System.Windows.Forms.DataGridView object.
bindingSource.DataSource = boundTable

---------------------------------------------------------------------------------------------------------------------------------------------------------------

در #C:

// Bind the System.Windows.Forms.DataGridView object
// to the System.Windows.Forms.BindingSource object.
dataGridView.DataSource = bindingSource;

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable orders = ds.Tables["SalesOrderHeader"];

// Query the SalesOrderHeader table for orders placed
// after August 8, 2001.
IEnumerable<DataRow> query =
from order in orders.AsEnumerable()
where order.Field<DateTime>("OrderDate") > new DateTime(2001, 8, 1)
select order;

// Create a table from the query.
DataTable boundTable = query.CopyToDataTable<DataRow>();

// Bind the table to a System.Windows.Forms.BindingSource object,
// which acts as a proxy for a System.Windows.Forms.DataGridView object.
bindingSource.DataSource = boundTable;


---------------------------------------------------------------------------------------------------------------------------------------------------------------

ایجاد یک متد CopyToDataTable<T> سفارشی
متدهای CopyToDataTable کنونی، فقط روی یک منبع IEnumerable<T>، یعنی جاییکه پارامتر ژنریک T، نوعی DataRow محسوب می شود، عمل می کند. گرچه این موضوع مفید است، اما به جداول اجازه نمی دهد از یک sequence انواع عددی (scalar) و queryهایی که انواع ناشناس را بازمی گردانند، یا از queryهایی که پیوند جداول را اجرا می کنند ایجاد شود.



---------------------------------------------------------------------------------------------------------------------------------------------------------------
در VB:

Public Class Item
Private _Id As Int32
Private _Price As Double
Private _Genre As String

Public Property Id() As Int32
Get
Return Id
End Get
Set(ByVal value As Int32)
_Id = value
End Set
End Property

Public Property Price() As Double
Get
Return _Price
End Get
Set(ByVal value As Double)
_Price = value
End Set
End Property

Public Property Genre() As String
Get
Return _Genre
End Get
Set(ByVal value As String)
_Genre = value
End Set
End Property

End Class
Public Class Book
Inherits Item
Private _Author As String
Public Property Author() As String
Get
Return _Author
End Get
Set(ByVal value As String)
_Author = value
End Set
End Property
End Class

Public Class Movie
Inherits Item
Private _Director As String
Public Property Director() As String
Get
Return _Director
End Get
Set(ByVal value As String)
_Director = value
End Set
End Property

End Class


---------------------------------------------------------------------------------------------------------------------------------------------------------------


در #C:

public class Item
{
public int Id { get; set; }
public double Price { get; set; }
public string Genre { get; set; }
}

public class Book : Item
{
public string Author { get; set; }
}

public class Movie : Item
{
public string Director { get; set; }
}


-------------------------------------------------------------------------------------------------
مثال
این مثال، یک پیوند بین جداول SalesOrderHeader و SalesOrderDetail را اجرا می کند تا سفارش های آنلاین ماه آگوست را بدست بیاورد و جدولی را از query ایجاد می کند.
در VB:


' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)

Dim orders As DataTable = ds.Tables("SalesOrderHeader")
Dim details As DataTable = ds.Tables("SalesOrderDetail")


Dim query = _
From order In orders.AsEnumerable() _
Join detail In details.AsEnumerable() _
On order.Field(Of Integer)("SalesOrderID") Equals _
detail.Field(Of Integer)("SalesOrderID") _
Where order.Field(Of Boolean)("OnlineOrderFlag") = True And _
order.Field(Of DateTime)("OrderDate").Month = 8 _
Select New With _
{ _
.SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
.SalesOrderDetailID = detail.Field(Of Integer)("SalesOrderDetailID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate"), _
.ProductID = detail.Field(Of Integer)("ProductID") _
}

Dim table As DataTable = query.CopyToDataTable()


---------------------------------------------------------------------------------------------------------------------------------------------------------------
در #C:

// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);

DataTable orders = ds.Tables["SalesOrderHeader"];
DataTable details = ds.Tables["SalesOrderDetail"];

var query =
from order in orders.AsEnumerable()
join detail in details.AsEnumerable()
on order.Field<int>("SalesOrderID") equals
detail.Field<int>("SalesOrderID")
where order.Field<bool>("OnlineOrderFlag") == true
&& order.Field<DateTime>("OrderDate").Month == 8
select new
{
SalesOrderID =
order.Field<int>("SalesOrderID"),
SalesOrderDetailID =
detail.Field<int>("SalesOrderDetailID"),
OrderDate =
order.Field<DateTime>("OrderDate"),
ProductID =
detail.Field<int>("ProductID")
};

DataTable orderTable = query.CopyToDataTable();

مثال
مثال زیر، یک collection برای آیتمهای قیمتهای بالاتر از 9.99 دلار query می کند و یک جدول از خروجی های query ایجاد می کند.
در VB:

Dim book1 As New Book()
book1.Id = 1
book1.Price = 13.5
book1.Genre = "Comedy"
book1.Author = "Gustavo Achong"

Dim book2 As New Book
book2.Id = 2
book2.Price = 8.5
book2.Genre = "Drama"
book2.Author = "Jessie Zeng"

Dim movie1 As New Movie
movie1.Id = 1
movie1.Price = 22.99
movie1.Genre = "Comedy"
movie1.Director = "Marissa Barnes"

Dim movie2 As New Movie
movie2.Id = 1
movie2.Price = 13.4
movie2.Genre = "Action"
movie2.Director = "Emmanuel Fernandez"

Dim items(3) As Item
items(0) = book1
items(1) = book2
items(2) = movie1
items(3) = movie2

' Query for items with price greater than 9.99.
Dim query = From i In items _
Where i.Price > 9.99 _
Order By i.Price _
Select New With {i.Price, i.Genre}

Dim table As DataTable
table = query.CopyToDataTable()

---------------------------------------------------------------------------------------------------------------------------------------------------------------
در #C:

// Create a sequence.
Item[] items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};

// Query for items with price greater than 9.99.
var query = from i in items
where i.Price > 9.99
orderby i.Price
select i;

// Load the query results into new DataTable.
DataTable table = query.CopyToDataTable();

مثال
مثال زیر، یک collection برای آیتمهای قیمتهای بالاتر از 9.99 دلار query می کند و خروجی ها رانمایش می دهد. Sequence بازگردانده شده انواع ناشناس در یک جدول موجود بارگذاری می کند.

در VB:

Dim book1 As New Book()
book1.Id = 1
book1.Price = 13.5
book1.Genre = "Comedy"
book1.Author = "Gustavo Achong"

Dim book2 As New Book
book2.Id = 2
book2.Price = 8.5
book2.Genre = "Drama"
book2.Author = "Jessie Zeng"

Dim movie1 As New Movie
movie1.Id = 1
movie1.Price = 22.99
movie1.Genre = "Comedy"
movie1.Director = "Marissa Barnes"

Dim movie2 As New Movie
movie2.Id = 1
movie2.Price = 13.4
movie2.Genre = "Action"
movie2.Director = "Emmanuel Fernandez"

Dim items(3) As Item
items(0) = book1
items(1) = book2
items(2) = movie1
items(3) = movie2

' Create a table with a schema that matches that of the query results.
Dim table As DataTable = New DataTable()
table.Columns.Add("Price", GetType(Integer))
table.Columns.Add("Genre", GetType(String))

' Query for items with price greater than 9.99.
Dim query = From i In items _
Where i.Price > 9.99 _
Order By i.Price _
Select New With {i.Price, i.Genre}

query.CopyToDataTable(table, LoadOption.PreserveChanges)


---------------------------------------------------------------------------------------------------------------------------------------------------------------
در #C:

// Create a sequence.
Item[] items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};

// Create a table with a schema that matches that of the query results.
DataTable table = new DataTable();
table.Columns.Add("Price", typeof(int));
table.Columns.Add("Genre", typeof(string));

var query = from i in items
where i.Price > 9.99
orderby i.Price
select new { i.Price, i.Genre };

query.CopyToDataTable(table, LoadOption.PreserveChanges);


مثال زیر، یک collection برای آیتمهای قیمتهای بالاتر از 9.99 دلار query می کند و خروجی ها رانمایش می دهد. Sequence بازگردانده شده انواع ناشناس در یک جدول موجود بارگذاری می کند. Schemaی جدول به طور اتوماتیک بسط پیدا می کند زیرا انواع Book و Movies از نوع Item مشتق می شوند.

---------------------------------------------------------------------------------------------------------------------------------------------------------------
در VB:

Dim book1 As New Book()
book1.Id = 1
book1.Price = 13.5
book1.Genre = "Comedy"
book1.Author = "Gustavo Achong"

Dim book2 As New Book
book2.Id = 2
book2.Price = 8.5
book2.Genre = "Drama"
book2.Author = "Jessie Zeng"

Dim movie1 As New Movie
movie1.Id = 1
movie1.Price = 22.99
movie1.Genre = "Comedy"
movie1.Director = "Marissa Barnes"

Dim movie2 As New Movie
movie2.Id = 1
movie2.Price = 13.4
movie2.Genre = "Action"
movie2.Director = "Emmanuel Fernandez"

Dim items(3) As Item
items(0) = book1
items(1) = book2
items(2) = movie1
items(3) = movie2

' Load into an existing DataTable, expand the schema and
' autogenerate a new Id.
Dim table As DataTable = New DataTable()
Dim dc As DataColumn = table.Columns.Add("NewId", GetType(Integer))
dc.AutoIncrement = True
table.Columns.Add("ExtraColumn", GetType(String))

Dim query = From i In items _
Where i.Price > 9.99 _
Order By i.Price _
Select New With {i.Price, i.Genre}

query.CopyToDataTable(table, LoadOption.PreserveChanges)

---------------------------------------------------------------------------------------------------------------------------------------------------------------
در #C:

// Create a sequence.
Item[] items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};

// Load into an existing DataTable, expand the schema and
// autogenerate a new Id.
DataTable table = new DataTable();
DataColumn dc = table.Columns.Add("NewId", typeof(int));
dc.AutoIncrement = true;
table.Columns.Add("ExtraColumn", typeof(string));

var query = from i in items
where i.Price > 9.99
orderby i.Price
select new { i.Price, i.Genre };

query.CopyToDataTable(table, LoadOption.PreserveChanges);

مثال
مثال زیر، یک collection برای آیتمهای قیمتهای بالاتر از 9.99 دلار query می کند و sequence دوبل (double) را باز می گرداند، و در یک جدول جدید بارگذاری می شود.
در VB:

Dim book1 As New Book()
book1.Id = 1
book1.Price = 13.5
book1.Genre = "Comedy"
book1.Author = "Gustavo Achong"

Dim book2 As New Book
book2.Id = 2
book2.Price = 8.5
book2.Genre = "Drama"
book2.Author = "Jessie Zeng"

Dim movie1 As New Movie
movie1.Id = 1
movie1.Price = 22.99
movie1.Genre = "Comedy"
movie1.Director = "Marissa Barnes"

Dim movie2 As New Movie
movie2.Id = 1
movie2.Price = 13.4
movie2.Genre = "Action"
movie2.Director = "Emmanuel Fernandez"

Dim items(3) As Item
items(0) = book1
items(1) = book2
items(2) = movie1
items(3) = movie2

Dim query = From i In items _
Where i.Price > 9.99 _
Order By i.Price _
Select i.Price

Dim table As DataTable
table = query.CopyToDataTable()

---------------------------------------------------------------------------------------------------------------------------------------------------------------
در #C:

// Create a sequence.
Item[] items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};

// load sequence of scalars.
IEnumerable<double> query = from i in items
where i.Price > 9.99
orderby i.Price
select i.Price;

DataTable table = query.CopyToDataTable();


و من اله التوفیق

TKNC
18-09-2010, 07:03
بخش سوم
معرفی امکانات و قابلیت های LINQ برای مدیران پروژه ها

LINQ to SQL به برنامه نویسان .NET اجازه نوشتن queryها را درزبان .NET می دهد تا بتوانند داده ها را از بانک اطلاعاتیSQL Server بازیابی و تغییر دهند. به طور عام، LINQ to SQL اجازه ایجاد queryهای SQL در syntax زبان.NET انتخابی مان و کار کردن با مجموعه ای قوی از اشیا به عنوان نتیجه برگشتی را به ما می دهد. می توان تغییراتی را در این اشیا بوجود آورد و سپس دوباره آنها را در database ذخیره کرد.
برای درک مفهوم syntax در LINQ to SQL، ما از schemaی بانک اطلاعاتی SQL زیر استفاده می کنیم که نرم افزاری ساده برای ثبت محصولات و helpdesk است؛ و با داده های نمونه populate شده و دارای روابط کلید خارجی (foreign-key relationship) است که در جای مناسب تعریف می شود.
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

SQL Database Schemaکه برای مثالهای LINQ to SQL استفاده می شود:
از شما می خواهم چند دقیقه این واقعیت را فراموش کنید که ما برضد نوع داده ای HookedOnLINQ کد نوییس می کنیم، بعداً توضیح خواهم داد که چگونه آن را در چند صفحه ایجاد کردم، فعلاً مد نظر داشته باشید که این، یک ساختار شی است که از این database schema تقلید می کند.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید



:Output
Mack Kamph b.17-Sep-1977
Armando Valdes b.09-Dec-1973




عبارت LINQ to SQL Query در بانک اطلاعاتی SQL Server– مخاطبان کمتر از 35 سال سن، ابتدا جوانترین.
هنگامی که حلقه foreach را وارد می کنیم، عبارت SQL زیر توسط LINQ فرموله می شود و روی سرور اجرا می شود. (دانستن این نکته مهم است که SQL فقط اولین باری که ما داده ها را request می کنیم اجرا می شود، تا آن موقع، query به صورت یک عبارت در حافظه نگهداری می شود این فرآیند، Deferred Execution نامیده می شود).


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


عبارات SQL که توسط LINQ ایجاد شده و مخاطبین بیشتر از تاریخی معین شده را که به عنوان یک پارامتر ارسال شده، باز می گرداند.
عبارت query در C#، به کد SQL پارامتریزه شده تبدیل شد، پارامترها ایجاد شدند و query روی سرور اجرا شد. LINQ to SQL به برنامه نویسان اجازه می دهد به استفاده از stored procedureها به جای SQL ادامه دهند، گرچه حالا مجبورید خودتان کد stored procedure را بنویسید، و در نتیجه بعضی از قابلیت های LINQ را از دست می دهید. بعداً در مورد این موضوع بیشتر بحث می کنیم، فعلاً در نظر داشته باشید که LINQ to SQL ازstored procedure و همچنین از فراخوانی های SQL که به طور دینامیکی ایجاد شده اند، در هر شرایطی ساپورت می کند.
اگر بانک اطلاعاتی شما دارای روابط کلید خارجی است، آنگاه سلسله مراتب آنها در مدلهای شی ایجاد شده منعکس می شود. می توان از طریق تعیین کردن جدول child به داده های رکوردهای مربوط دسترسی پیدا کنید. مثال بعدی نشان می دهد چگونه می توان در زنجیره روابط کلید خارج، بدون یک عبارت Join به طور مستقیم navigate کرد.



برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


Output:
Barney Gottshall - Asset Blaster v1
Barney Gottshall - Asset Blaster v1.1
Armando Valdes - Asset Blaster Pro v1
Jeffery Deane - Asset Blaster Pro v1.1
Stewart Kagel - Asset Blaster Pro v1.1
Blaine Reifsteck - Asset Blaster Pro v1.1
Ariel Hazelgrove - Asset Blaster v1.1

دسترسی به روابط کلید خارجی ساده است. نیازی به join syntax نیست، مستقیماً به زیر اعضا (sub-members) دسترسی دارید.
این مدل شی سلسله مراتبی (hierarchical)، برای آپدیت ها نیز جواب می دهد. می توانید رکوردها را بوسیله تغییر داده اشیا و اضافه یا حذف کردن اشیا از جداول، در جداول مربوطه assign، اضافه یا حذف کنید. در پشت پرده، LINQ to SQL، فرمان SQL query زیر را ایجاد و آنرا اجرا می کند. از این نتایج برای populate کردن مجموعه شی نتیجه (result object collection) استفاده کرد که مجموعه ای از یک type ناشناس (Anonymous) است.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


کد SQL که نشان می دهد چگونه joins to related table through foreign-keys، اضافه شدند.
اگر بانک اطلاعاتی شما دارای روابط کلید خارجی نیست که بین دو جدول تعریف می شوند، LINQ to SQL، دسترسی نسبی (relational access) را توسط تعیین Joinها در عبارات query، قبول می کند. Query زیر چگونگی join کردن را در جاییکه یک کلید خارجی بین دو جدول Contacts.Phone و CallLogs.Number تعریف نشده، نشان می دهد.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


اگر هیچ کلید خارجی وجود نداشته باشد، می توانید از اپراتور Join در عبارت query استفاده کنید.
جهت تغییر دادن و اضافه کردن رکورد به بانک اطلاعاتی مان، فقط باید تغییراتی رابه اشیای موجود در حافظه اعمال کنید و سپس متد SubmitChanges را فراخوانی کنید (مواظب باشید، من یک بار به اشتباه متد AcceptChanges را فرا خواندم که تغییرات را قبول می کند و همه رکوردها را به صورت اریجینال mark می کند اما در database ذخیره نمی کند. LINQ to SQL، رد تغییرات را نگه می دارد و عبارات SQL را ایجاد می کند تا همه آپدیت ها، insertها، و deleteها را تحت تاثیر قرار دهد. می توانید این رفتار پیش فرض را Override کنید و متدهای پیاده سازی خودتان را تعیین کنید و به جای آن استفاده کنید. LINQ to SQL، یک تراکنش را در اطراف آپدیت های database ایجاد می کند، پس اگر قسمتی دچار اشکال شود، فرصت دارید تا error را capture کنید، آنرا اصلاح و دوباره تلاش کنید. همچنین می توانید کنترل کنید LINQ to SQL چگونه errorهای همزمان را مدیریت کند (وقتی شخص دیگری داده هایی را که قبلاً ویرایش می کردید تغییر می دهد، شما شانس ذخیره کردن را دارید).

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


آپدیتی که چگونگی مدیریت کردن errorهای همزمان را نشان می دهد. شما تغییرات را در اشیا ایجاد می کند و سپس SubmitChanges را فرا می خوانید.
Insert کردن رکوردهای جدید به سادگی ایجاد نمونه جدیدی از اشیا و اضافه کردن آن به مجموعه ی مناسب و سپس فراخوانی SubmitChanges است.


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


insert کردن یک رکورد جدید و یک زیر رکورد مرتبط. فقط اشیا را ایجاد کنید و به یک collection اضافه کنید.
LINQ to SQL در SubmitChanges، عبارات SQL را به ترتیب صحیحی generate می کند تا رکوردهای جدید را در database ذخیره کند و هر کدام را به طور صحیح reference کند. در این مثال، LINQ to SQL، به insert کردن Contact جدید نیاز دارد تا ابتدا کلید اصلی را بدست بیاورد و سپس آنرا هنگام نوشتن ترتیب جدید در database استفاده کند. کل فرآیند دریک transaction انجام می شود، پس اگر هر مرحله ای دچار اشکال شود، آنگاه کل database به حالتی که قبل از اینکه SubmitChanges فراخوانده شود، بر میگردد.


Start LOCAL Transaction (ReadCommitted)


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


Commit LOCAL Transaction


SQL هنگام نوشتن یک رکورد و زیر رکورد، اجرا می شود. به wrap کردن کل فرآیند توسط transaction دقت کنید.
این رکوردها بعد از اینکه متد SubmitChanges در مثال شکل 16 فراخوانی شود، اضافه می شوند.
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

حذف کردن رکوردها بسیار ساده است. می توانید یک شی را از مجموعه اشیایی که در حال حاضر در حافظه هستند و از query قبلی جمع آوری شده اند، حذف کنید.


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


مثال هایی ازحذف کردن رکوردها از database
تا اینجا من یک مرحله مهم را حذف کرده ام. ما queryهایی را ضد یک type بنام HookedOnLINQ نوشته ایم که با یک database connection string، و instance types Contacts، و Orders، و Products شروع شده است. این type، از لنگر LINQ to SQL، کلاسی به نام DataContext، ارث می برد. این کلاس، marshalling عبارات query را به عبارات SQL ، و همچنین change tracking را در فراخوانی SubmitChanges مدیریت می کند. به علاوه، ما به داشتن typeهایی برای نمایش جداول داده هایمان و جنبه های mapping اشیا و روابط با معادل های SQLشان و بالعکس، نیاز داریم. گرچه همه این کلاسها را می توان به طور دستی ایجاد کرد، اما این کار اصلاً توصیه نمی شود. یک ساپورت زمان طراحی و درونی در Visual Studio به همراه یک ابزار خط فرمان (command line tool) وجود دارد که کل کارهای سنگین در code generation به جای ما انجام می دهد.
کلاس DataContext سفارشی:
• از System.Data.DLINQ.DataContext type ارث می برد
• مجموعه ای از instance type را آغاز می کند (Table<[type]>) و آنها را قابل دسترس می کند. (مثلاً، می توانیم db.Contacts را از میان عبارات query فرابخوانیم)
کلاس های instance object سفارشی:
• با یک صفت [Table] تغییر شکل می دهد
• حاوی fieldهای رایج یا propertyهایی است که با صفات [Column] تغییر شکل داده اند
• روابط کلید خارجی با صفت [Association] را تعریف می کنند
• رفتار Update، Insert، و Delete را با تعریف متدهایی که با صفات [Update]، [Insert]، و [Delete] علامتگذاری (mark) شده اند را override می کند
• Store Procedure، View، و Function wrapperها را با متدهایی که با صفات [StoredProcedure]، [View]، یا [Function] علامتگذاری (mark) شده اند را تعریف می کند
• تضمین می کند که رویدادهای PropertyChanging و PropertyChanged، هروقت که value تغییر می کند، روی می دهند.

گزینه هایی برای generate کردن کلاس های wrapper و مشتق DataContext، که عملکرد LINQ to SQL را روی جداول و اشیای databaseهای دیگر قبول می کنند، در زیر آورده شده:
• کل کار را به طور دستی انجام دهیم؛
• از built-in designer برای Visual Studio 2005 استفاده کنیم؛
• از ابزار خط فرمان SQLMetal استفاده کنیم؛
• از یک فایل XML mapping برای لینک کردن جداول و ستونهای database به typeها و propertyها استفاده کنیم. این کار به database و تغییرات mapping، اجازه می دهد در recompile کردن یک برنامه روی دهند.
برای generateکردن object wrapper برای بانک اطلاعاتی نمونه، بنام HookedOnLINQ، باید برنامه SqlMetal را با استفاده از ابزار خط فرمان و با argumentهای زیر اجرا کنید:
sqlmetal /server:(local) /database:HookedOnLINQ /code:HookedOnLINQ.cs
این کار، یک HookedOnLINQ.cs ایجاد می کند که برای تمامی مثال هایی که تا الان آورده شده اند، کاملاً کاربردی است. من فقط آن را درون پروژه اصلی کپی کردم و solution را compile کردم.
built-in designer به شما اجازه ایجاد یک DLINQ Object surface را می دهد. می توانید table instanceها را از پنجره Server Explorer، روی آن surface درگ کنید.روابط کلید خارجی به طور اتوماتیک به surface اضافه می شوند، اگر در بانک اطلاعاتی تعریف شوند، یا می توانید به طور دستی آنها را از Toolbox اضافه کنید. هنگام compile کردن، DataContext و instance typeها برای شما ایجاد می شوند. در زیر یک DLINQ Object surface آمرده شده که schemaی HookedOnLINQ را از بانک اطلاعاتی نشان می دهد.


[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

LINQ to SQL Designer Surface. درگ کردن جدول ها از server explorer باعث ایجاد object model می شود و به طور اتوماتیک روابط را تعریف می کند.
متد جایگزین استفاده از صفات که مدل رابطه ای را به مدل شی ای لینک می کند، منتقل کردن mappingها به یک فایل XML است. ابزار خط فرمان SQLMetal، این فایل XML را برای شما ایجاد می کند، اما می توانید generate کردن آنرا هرطور که دوست دارید اتوماتیک کنید. وقتی که DataContext را ایجاد می کنید، می توانید mapping XML را ارسال کنید، و این کار دقیقاً همان تاثیر استفاده از صفات را خواهد داشت، غیر از اینکه، هنگام compile کردن، به برنامه شما hardcode نمی شود.
خیلی ها معتقدند که database access همیشه باید از طریق Stored Procedure اجرا شوند تا امنیت را ارتقا دهند. LINQ to SQL به طور کامل Stored Procedureها را برای فراخوانی های عمومی و عملیات های update، insert، و delete، ساپورت می کند؛ و در موارد زیادی، تجربه شما را با خلاص کردن شما از ایجاد پارامترهای ورودی توسط دست، افزایش می دهد. اما، استفاده محض از Stored Procedureها، مزایای نوشتن عبارت های Query را در زبان برنامه نویسی اصلی برنامه نویس، از بین می برد. می توان از Stored Procedureها برای همه عملیات های Insert، Update، و Delete بکار برد و از عبارات Query برای بازیابی داده ها استفاده کرد. این کار باعث محافظت database در برابر از بین رفتن داده ها می شود، و به برنامه نویسان اجازه می دهد عبارات Query را در VB یا C# بسازند.
فراخوانی stored procedureها بسیار راحت شده. هنگام استفاده از ADO.NET، مجبور بودید قبل از ایجاد یک connection به database، و فراخوانی واقعی stored procedureها، پارامترهایی را به طور دستی بسازید. ابزار generate کردن، به عنوان بخشی از LINQ to SQL، تابع های wrapper را برای stored procedureها ایجاد می کند.
کد stored procedure زیر، لیستی از پرداختهای سررسیده را بازیابی می کند. روزهایی که از موعد پرداخت گذشته، به عنوان یک پارامتر ارسال می شود. نتیجه این کار، یک cursor با تعدادی ستون است، که یقیناً آن type نیست که قبلاً در اشیاء C# تعریف کرده ایم.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


ابزار generate کردن کد، دارای یک switch است که wrapper و result type را برای stored procedureها، generate می کند.


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

TKNC
21-09-2010, 12:55
بخش چهارم

LINQ To SQLL

مقدمه
شرکت ماکروسافت، Language Integrated Query یا LINQ را همراه با.NET Framework 3.5 معرفی کرد. LINQ، برنامه نویسان را قادر به query کردن منبع داده ها با استفاده از یک query مانند syntax با C# و VB.NET می کند. این منبع داده ها می توانند collectionها، بانک های اطلاعاتی SQL Server، XML، و datasetها باشند. به غیر از آنچه که از طرف Microsoft تامین می شود، LINQ گستردنی هم هست. این بدین معناست که شما می توانید منابع داده ها را فراتر از آنچه که مایکروسافت ship میکند، query کنید. مثال هایی از چنین پیاده سازی هایی عبارتند از LINQ To Flickr، LINQ To Amazon، LINQ to Google، و غیره. در این مقاله نشان می دهم چگونه می توان از LINQ To SQL جهت اجرای عملیات های CRUD روی یک بانک اطلاعاتی SQL Server استفاده کرد. من از بانک اطلاعاتی Northwind استفاده می کنم و یک برنامه ASP.NET می سازم تا قابلیت های LINQ To SQL را نشان دهم. شما می توانید بانک اطلاعاتی Northwind را از اینجا ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]) دانلود کنید.
ابزار های لازم برای این مقاله:

1. Visual Studio 2008
2. .NET Framework 3.5
3. SQL Server 2005
ساختار راه حل (Solution Structure)

برای این مقاله، به دو پروژه نیاز داریم. یکی data layer است که generate خواهیم کرد، و دیگری یک برنامه تحت وب ASP.NET است. ساختار راه حل در Solution Explorer، شبیه مثال زیر است.
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
ایجاد Data Layer

قبل از اینکه data layer را generate کنیم، باید یک connection در Server Explorer ایجاد کنیم که به بانک اطلاعاتی Northwind اشاره می کند.
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
حالا data layerمان را با استفاده LINQ To SQL ایجاد می کنیم. برای انجام این کار، باید یک item جدید به پروژه data layer از نوع کلاسهای LINQ to SQL اضافه کنیم. نام آن را Northwind می گذاریم، همانگونه که در زیر نشان داده شده.
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
بعد از اضافه کردن یک کلاس LINQ to SQL، با یک designer surface روبرو می شویم. دراینجا تنها جداول را drag می کنیم که بخشی از data layer خواهد شد. در این مقاله، ما همه جداول را از طریق انتخاب کردن همه آنها در یک حرکت، روی designer، drag می کنیم. Designer ما باید بعد از drag کردن همه جداول روی آن شبیه شکل زیر باشد.
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
حالا باید solution را بسازیم تا مطمئن شویم همه چیز ok است. ما با موفقیت data layer مان را نصب کرده ایم. در Solution Explorer می بینم که دو فایل جدید داریم، یعنی Northwind.dbml.layout و Northwind.designer.cs. همچنین می بینیم که referenceهای لازم برای complie و run کردن کدمان نیز توسط Visual Studio اضافه شده اند.
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
فایل .cs حاوی کدی برای data layer ماست. بیایید کدی را که برای ما ایجاد شده، امتحان کنیم. نگاهی به کلاس Region خواهیم انداخت.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید



این کلاس با صفت Table، آمیخته شده و برای خصوصیت Name، نام واقعی جدولی که در بانک اطلاعاتی مان موجود است، تخصیص داده شده. کلاس Region نیز interfaceهای InotifyPropertyChangingو INotifyPropertyChanged را پیاده سازی می کند. این interfaceها برای databinding بکار می روند. کلاس Region همچنین حاوی یک خصوصیت (property)برای هر ستون است. بیایید نگاهی به خصوصیت RegionDescription بیاندازیم.


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید



ستون ها با صفت Column آمیخته شده اند و valueها برای storasge ارسال می شوند، DbType و CanBeNull نشان می دهند آیا ستون null است یا خیر.
استفاده از Data Layer

حالا که data layer را ایجاد کرده ایم، روی برنامه های تحت وب ASP.NET کار خواهیم کرد، یعنی جاییکه data layer را خواهیم دید. در ابتدا یک web form ایجاد می کنیم تا مشتری ها را جستجو کنیم و نتایج را نمایش دهیم. همچنین یک web form ایجاد می کنیم تا مشتری های جدید را وارد کنیم. بیایید با web form برای جستجوی مشتری ها شروع کنیم؛ برای این کار، از صفحه Default.aspx استفاده خواهیم کرد. تعداد کمی کنترل روی web form قرارمی دهیم. این کنترل ها، پارامترهای جستجو و یک دکمه در اختیار ما می گذارد که وقتی رویش کلیک کنیم، جستجو را انجام می دهند و نتایج را نمایش می دهد. شکل زیر نمایی از فرم بعد از قرار دادن کنترل هاست:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
همچنین یک کنترل GridView روی فرم مان قرار می دهیم تا نتایج جستجو را نمایش دهد. حالا مقداری کد در event handler کلیک دکمه قرار می دهیم تا جستجو را انجام دهد و نتایج را در GridView نمایش دهد. باید مطمئن شوید که یک reference به پروژه Data Layer، System.Data.Linq و عبارت مناسب وجود دارد. در زیر آنچه که event handler کلیک دکمه دربرخواهد گرفت، آورده شده است:


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید


این کد، جدول مشتریان را در بانک اطلاعاتی northwind، query می کند و همه مشتری ها را باز می گرداند. حالا باید کمی آن را modify کنیم تا نام مشتری ها و نام شرکت ها را به عنوان پارانترهایی برای queryمان قبول کند. event handler بعد از modify کردن به صورت زیر خواهد بود:


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

حالا نتایج جستجو فیلتر می شود.
حالا بیایید یک فرم data entry برای مشتری ها ایجاد کنیم. باید یک web form جدید در پروژه ASP.NET مان وارد کنیم و آن را CustomerEntry بنامیم. برای شروع باید مطمئن شویم که فرم ما حاوی fieldهای لازم برای وارد کردن یک مشتری جدید است. فرم ما بعد از تکمیل شبیه نمونه شکل یر خواهد بود.
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]
انتظار ما این است که هنگامی که روی دکمه Save Customer کلیک می کنیم، یک ردیف (row) جدید به جدول مشتری ها اضافه شود. کد زیر این کار را برای ما انجام می دهد.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید



می توان یک ستون که از قبل در بانک اطلاعاتی موجود است را ابتدا توسط بازیابی داده ها و سپس توسط submit کردن آن از طریق DataContext، آپدیت کرد.
نتیجه گیری

در این مقاله، ما فقط یک عبارت SQL مستقل ننوشتیم تا داده ها را به یک بانک اطلاعاتی وارد کنیم یا آن را بازیابی کنیم. این، زیبایی LINQ To SQL است. به علاوه، کد بازیابی ما هنگامی که در C# است بسیار شبیه یک query است. باید از مزایای چنین روش موثر و یکپارچه ای برای کار کردن با داده ها قدردانی کرد.