مطالب
کار با Docker بر روی ویندوز - قسمت ششم - کار با بانک‌های اطلاعاتی درون Containerها
تا اینجا نحوه‌ی اجرای برنامه‌ها را داخل کانتینرها بررسی کردیم؛ اما هنوز در مورد داده‌های آن‌ها بحث نکرده‌ایم. اگر بانک‌های اطلاعاتی را به درون کانتینرها منتقل کنیم، چه بر سر داده‌های آن‌ها می‌آید؟


بررسی روش اجرای MS SQL Server Express درون یک Container

اگر مخازن Imageهای رسمی مایکروسافت را در داکرهاب بررسی کنیم، به مخازنی مانند mssql-server-windows-express ، mssql-server و یا mssql-server-linux نیز خواهیم رسید. در اینجا آخرین نگارش Image مربوط به SQL Server Express آن، حدود 7GB حجم دارد. برای دریافت آن ابتدا به Windows Containers سوئیچ کنید و سپس دستور زیر را صادر نمائید:
 docker pull microsoft/mssql-server-windows-express
پس از دریافت آن، اگر به مستندات رسمی آن در داکر هاب مراجعه کنیم، دستوری را به صورت زیر برای اجرای آن عنوان کرده‌است:
 docker run -d -p 1433:1433 -e sa_password=<SA_PASSWORD> -e ACCEPT_EULA=Y microsoft/mssql-server-windows-express
در این دستور:
- سوئیچ d سبب می‌شود تا پس از اجرای این دستور، بلافاصله به command prompt بازگشت داده شویم و SQL Server Express در background اجرا شود.
- سپس پورت 1433 میزبان به پورت 1433 کانتینر، نگاشت شده‌است که پورت استاندارد SQL Server است.
- سوئیچ e، امکان تنظیم متغیرهای محیطی را میسر می‌کند؛ برای مثال ورود کلمه‌ی عبور کاربر SA و یا پذیرش مجوز آن. برای نمونه، این کلمه‌ی عبور را مساوی password وارد کنید؛ هرچند کار نخواهد کرد، اما بررسی خطاهای به همراه آن مفید است.
- و در آخر نام image مرتبط ذکر شده‌است.

پس از اجرای این دستور، کانتینر SQL Server Express، در پس زمینه شروع به کار خواهد کرد و بلافاصله به خط فرمان بازگشت داده می‌شویم. در اینجا ممکن است آغاز SQL Server اندکی طول بکشد. برای اینکه دریابیم در این لحظه وضعیت پروسه‌ی آن به چه صورتی است، دستور docker logs id را صادر کنید. پس از آن خطایی مانند password validation failed را مشاهده خواهیم کرد. عنوان می‌کند که پیچیدگی کلمه‌ی عبور وارد شده کافی نیست.

یک نکته: زمانیکه دستور docker run را اجرا می‌کنیم، یک هش طولانی را نمایش می‌دهد و پس از آن به خط فرمان بازگشت داده می‌شویم. این هش طولانی، همان id کانتینر در حال اجرا است. برای مثال در دستور docker logs id می‌توان 3 حرف ابتدای این هش را بجای id وارد کرد. البته این id را توسط دستور docker ps نیز می‌توان بدست آورد.

بنابراین با توجه به اینکه دستور docker logs id، خطایی را گزارش کرده‌است، توسط دستور docker stop id، این کانتینر را متوقف کرده و آن‌را مجددا با کلمه‌ی عبوری مانند pass!w0rd1 اجرا می‌کنیم:
 docker run -d -p 1433:1433 -e sa_password=pass!w0rd1 -e ACCEPT_EULA=Y microsoft/mssql-server-windows-express
اینبار نیز مجددا دستور docker logs id را بر اساس id جدید این کانتینر اجرا می‌کنیم که پیام Started SQL Server را نمایش می‌دهد. بنابراین تا به اینجا موفق شدیم پروسه‌ی SQL Server Express را بدون مشکلی آغاز کنیم.


همانطور که در قسمت سوم نیز عنوان شد، اگر این کانتینر را بر روی ویندوز سرور، در حالت Windows Containers اجرا کنیم (و نه در حالت Hyper-V)، پروسه‌های اجرای شده‌ی داخل یک Container را می‌توان با Job Object Idهای یکسانی که دارند، در Task Manager ویندوز، در کنار سایر پروسه‌های سیستم، شناسایی کرد.


اتصال به SQL Server Express اجرا شده‌ی داخل یک Container توسط SQL Server Management Studio

پس از اجرای SQL Server Express دخل کانتینر، مطابق تنظیمات آن، چه در سیستم میزبان و چه در داخل کانتینر، به پورت 1433 گوش فرا داده می‌شود. به همین منظور نیاز است IP این کانتینر را نیز بدست آوریم. برای اینکار دستور ipconfig را در سیستم میزبان صادر کنید تا بر اساس مشخصات کارت شبکه‌ی مجازی آن، بتوان IP آن‌را بدست آورد (دستور docker inspect id نیز چنین اطلاعاتی را به همراه دارد). اکنون می‌توان از داخل سیستم راه دور دیگری که SQL Server Management Studio بر روی آن نصب است، توسط این IP و پورت، به SQL Server Express متصل شد.


البته در اینجا نیازی به ذکر پورت نیست؛ چون پورت 1433، شماره پورت پیش‌فرض است. بعد از اتصال، می‌توان کارهای متداولی مانند ایجاد یک بانک اطلاعاتی جدید را انجام داد.
برای آزمایش، یکبار دستور docker ps را صادر کنید تا id این کانتینر مشخص شود. سپس دستور docker stop id را صادر کنید تا پروسه SQL Server Express خاتمه یابد. اکنون اگر در SQL Server Management Studio قصد کار با آن‌را داشته باشیم، پیام عدم اتصال مشاهده می‌شود. اکنون برای اجرای مجدد کانتینر، دستور docker start id را صادر کنید.


بررسی روش اجرای MySQL داخل یک Container

برای اجرای MySQL نیاز است به Linux Containers سوئیچ کنیم. حجم tag ویژه‌ی latest آن نیز حدود 138MB است که نسبت به SQL Server Express هفت گیگابایتی، بسیار کمتر است!
در همان صفحه‌ی مستندات آن در داکرهاب، دستور اجرایی آن نیز ذکر شده‌است:
 docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
در اینجا نیز توسط سوئیچ e که مخفف environment است، یکسری از متغیرهای محیطی MySQL، مانند کلمه‌ی عبور آن قابل تنظیم هستند. همچنین سوئیچ d نیز برای اجرای آن در پس زمینه، ذکر شده‌است. همین دستور را به همین شکل، صرفا با حذف tag آن، جهت اشاره‌ی به آخرین نگارش موجود این image، اجرا می‌کنیم:
 docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql
با اجرای این دستور، در ابتدا MySQL از داکرهاب دریافت شده و سپس در پس زمینه اجرا خواهد شد. پیش از بازگشت به command prompt، یک هش طولانی نیز نمایش داده می‌شود که همان id کانتینر در حال اجرای آن است. برای اینکه بتوانیم ریز جزئیات رخ داده را بهتر مشاهده کنیم، می‌توان از دستور docker logs id استفاده کرد.

یک نکته: می‌توان یک command prompt جدید را باز کرد و سپس دستور docker logs -f id را در آن صادر کرد. به این صورت لاگ‌های لحظه‌ای یک کانتینر را نیز می‌توان مشاهده کرد (f در اینجا به معنای follow است).

اکنون می‌خواهیم MySQL Client موجود در همین Container در حال اجرا را، اجرا کنیم (اجرای پروسه‌ای درون یک کانتینر در حال اجرا). برای اینکار از دستور docker exec استفاده می‌شود:
docker ps
docker exec -it id mysql --user=root --password=my-secret-pw
ابتدا توسط دستور docker ps مقدار id این کانتینر را بدست می‌آوریم و سپس در دستور بعدی، از آن استفاده خواهیم کرد.
در اینجا توسط دستور docker exec ابتدا یک interactive shell را درخواست کرده‌ایم (اجرای foreground یک برنامه‌ی شل). سپس id این کانتینر باید ذکر شود. پس از آن نام فایل اجرایی MySQL Client قید شده و در پایان، نام کاربری و کلمه‌ی عبور اتصال به آن که در دستور docker run تنظیم شده‌اند، ذکر می‌شوند.
با اجرای این دستور، به خط فرمان MySQL Client داخل این کانتینر دسترسی پیدا می‌کنیم. در اینجا می‌توان دستورات مختلفی را برای کار با پروسه‌ی mysql اجرا کرد؛ مانند اجرای دستور show databases که لیست بانک‌های اطلاعاتی موجود را نمایش می‌دهد:
mysql> show databases;
use mysql;
show tables;
select * from user;
exit;


روش مدیریت داده‌های بانک‌های اطلاعاتی توسط Docker

در قسمت قبل دریافتیم که لایه‌ی رویی یک container، دارای قابلیت read/write است و برای مثال می‌توان فایل‌های یک وب سایت استاتیک را در آنجا کپی و سپس هاست کرد. اما این لایه، لایه‌ی مناسبی برای ذخیره سازی داده‌های یک بانک اطلاعاتی نیست. در اینجا برای مدیریت بهتر این نوع داده‌ها، از مفهومی به نام volume استفاده می‌شود.
برای درک روش مدیریت داده‌ها توسط داکر، دستور docker volume ls را اجرا کنید. مشاهده خواهید کرد که docker یک volume پیش‌فرض را نیز ایجاد کرده‌است. البته با volumes پیشتر در قسمت چهارم، در بخش «روش به اشتراک گذاری فایل سیستم میزبان با کانتینرها» نیز آشنا شده‌ایم. این volume پیش‌فرض، کار ذخیره سازی اطلاعات را حتی اگر کانتینری در حال اجرا نباشد نیز انجام می‌دهد. وجود یک چنین قابلیتی جهت از دست نرفتن اطلاعات ارزشمند ذخیره شده‌ی در بانک‌های اطلاعاتی بسیار ضروری است.
البته لازم به ذکر است، این volume ای را که در اینجا مشاهده می‌کنید، توسط Dockerfile خود mysql به صورت خودکار ایجاد می‌شود. برای مثال در داکرهاب، در قسمت full description این image، در ابتدای توضیحات قسمتی است به نام supported tags and respective dockerfile links. در اینجا هر tag نامبرده شده، در حقیقت لینکی است به یک Dockerfile. اگر یکی از آن‌ها را باز کنید، چنین سطری را در آن مشاهده خواهید کرد:
  VOLUME /var/lib/mysql
این دستور سبب می‌شود چنین مسیری (مسیر پیش‌فرض ثبت اطلاعات mysql) به صورت یک volume جدید، خارج از فایل سیستم کانتینر، بر روی سیستم میزبان، ایجاد شود. سپس این مسیر و volume جدید، توسط داکر به صورت خودکار به این کانتینر mount خواهد شد و برای این موارد نیازی نیست کار خاصی توسط ما انجام شود.
اینکار نه فقط برای بالابردن کارآیی اعمال read/write انجام شده‌ی توسط container انجام می‌شود، بلکه حتی اگر این کانتینر را توسط دستور docker rm id حذف کنیم، دستور docker volume ls، هنوز همان volume ای را که در حین نصب mysql به صورت خودکار ایجاد شده بود، نمایش می‌دهد. علت اینجا است که طول عمر این volume، وابسته‌ی به طول عمر کانتینر آن نیست. به این ترتیب حذف تصادفی یک کانتینر، سبب از دست رفتن اطلاعات ارزشمند داخل بانک اطلاعاتی آن نمی‌شود.


روش تعیین صریح یک volume برای یک کانتینر بانک اطلاعاتی، توسط volumeهای نامدار

دستور docker run ای را که برای اجرای mysql صادر کردیم، یک volume خودکار را ایجاد کرده‌است و اگر آن‌را با دستور docker volume ls بررسی کنیم، دارای یک نام هش مانند است که به آن anonymous volume هم گفته می‌شود. در ادامه قصد داریم یک volume نامدار را ایجاد کنیم و سپس از آن جهت ذخیره سازی اطلاعات چندین وهله از کانتینر mysql استفاده نمائیم.
پیش از ادامه بحث، ابتدا توسط دستور docker rm id، کانتینر mysql ای را که پیشتر ایجاد کردیم حذف کنید؛ هرچند این دستور، volume متناظر با آن‌را حذف نمی‌کند.
سپس برای اینکه یک کانتینر جدید mysql را با ذکر صریح volume آن ایجاد و اجرا کنیم، می‌توان از دستور زیر استفاده کرد:
 docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d -v db:/var/lib/mysql mysql
در اینجا از سوئیچ v برای ایجاد یک volume نامدار استفاده شده‌است و در آن بجای ذکر قسمت مسیر پوشه‌ای در سمت میزبان، صرفا یک نام، مانند db، پیش از ذکر : قید شده‌است. پس از :، مسیری که این volume قرار است در آن کانتینر به آن نگاشت شود، ذکر شده‌است.
اکنون اگر دستور docker volume ls را صادر کنیم، در لیست خروجی آن، نام db قابل مشاهده‌است.

در ادامه پروسه‌ی MySQL Client داخل این کانتینر را اجرا کرده:
 docker exec -it some-mysql mysql --user=root --password=my-secret-pw
و تغییراتی را به صورت زیر اعمال می‌کنیم:
mysql> show databases;
create database pets;
show databases;
exit;
در اینجا بانک اطلاعاتی جدید pets ایجاد شده‌است.

اکنون در ابتدا این کانتینر را متوقف کرده و سپس آن‌را حذف می‌کنیم:
docker ps
docker stop id
docker rm id
هرچند اگر دستور حذف را با سوئیچ f- نیز اجرا کنیم (به معنای force)، کار stop را به صورت خودکار انجام می‌دهد.

در ادامه مجددا همان دستور قبلی را که توسط آن volume نامداری، ایجاد کردیم، اجرا می‌کنیم:
 docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d -v db:/var/lib/mysql mysql
اینبار اگر دستور docker volume ls را مجددا صادر کنیم، مشاهده خواهیم کرد این کانتینر جدید، بجای ایجاد یک volume جدید، از همان volume موجود db که آن‌را پیشتر ایجاد کردیم، استفاده می‌کند؛ هرچند کانتینری که آن‌را ایجاد کرده‌است، دیگر وجود خارجی ندارد. در این حالت اگر MySQL Client این کانتینر را اجرا نمائیم:
 docker exec -it some-mysql mysql --user=root --password=my-secret-pw
و سپس دستور نمایش بانک‌های اطلاعاتی آن‌را صادر کنیم:
 mysql> show databases;
در خروجی آن هنوز بانک اطلاعاتی pets که پیشتر ایجاد شده بود، قابل مشاهده‌است. بنابراین حذف و یا ایجاد کانتینرها، تاثیری را بر روی volumeهای ایجاد شده، نخواهند داشت.


روش حذف volumes اضافی

با توجه به اینکه volumeها، طول عمر متفاوتی را نسبت به کانتینرها دارند، ممکن است پس از مدتی فضای دیسک سخت شما را پر کنند. برای مثال به ازای هربار اجرای دستور docker run مربوط با MYSQL با نامی متفاوت، یک volume جدید نیز ایجاد می‌شود.
خروجی دستور docker inspect id به همراه قسمتی است به نام mounts که خاصیت name آن، دقیقا مساوی نام volume متناظر با کانتینر بررسی شده‌است. همچنین خاصیت source آن، محل دقیق ذخیره سازی این volume را بر روی فایل سیستم میزبان مشخص می‌کند.
برای حذف آن‌ها، ابتدا نیاز است کانتینرها را متوقف کرد. دستور زیر تمام کانتینرهای در حال اجرا را متوقف می‌کند. در اینجا دستور docker ps -q، لیست id تمام کانتینرهای در حال اجرا را باز می‌گرداند (در این دستورات، افزودن پارامتر q، سبب بازگشت صرفا idها می‌شود):
 docker stop $(docker ps -q)
اگر می‌خواهید تمام کانتینرهای موجود را حذف کنید:
 docker rm $(docker ps -aq)
و یا دستور زیر ابتدا تمام کانتینرهای موجود را متوقف کرده و سپس آن‌ها را حذف می‌کند:
 docker rm -f $(docker ps -aq)
دستور زیر تمام volumes موجود را حذف می‌کند:
 docker volume rm $(docker volume ls -q)
دستور زیر یک کانتینر با id مشخص شده را به همراه volume نامگذاری نشده‌ی مرتبط با آن، متوقف و سپس حذف می‌کند:
 docker rm -fv id
دستور زیر، لیست تمام volumes غیراستفاده شده‌ی توسط کانتینرهای موجود را نمایش می‌دهد (به یک چنین volumeهای در اینجا dangling گفته می‌شود؛ volume ای که کانتینر آن حذف شده‌است):
 docker volume ls -f dangling=true
 که می‌تواند لیست مناسبی برای حذف باشند:
 docker volume rm $(docker volume ls -qf dangling=true)
نظرات مطالب
استفاده از لوسین برای برجسته سازی عبارت جستجو شده در نتایج حاصل
- بله. نیاز است مدام این ایندکس را به روز نگه داشت.
- برای این موارد متداول از تاریخ تا تاریخ، از همان SQL معمولی استفاده کنید. هر جایی که امکان تعریف ایندکس و کوئری‌های SQL ایی که از ایندکس استفاده می‌کنند، وجود دارد، روش‌های متداول SQLایی بهینه‌ترین روش‌ها هستند. هدف در اینجا، full text search است بر روی انبوهی text. جستجوی بسیار سریع روی فیلدهای ایندکس نشده حجیم متنی با کیفیتی بالا. این هدف full text search است. چیزی مثل جستجوی گوگل.
در غیر اینصورت نیاز خواهید داشت از عبارات sql به همراه like استفاده کنید که ... بسیار کند هستند؛ چون باید کل جداول و بانک اطلاعاتی را هربار اسکن کنند و در حالت استفاده از like از ایندکس استفاده نمی‌شود.
مطالب
آشنایی با Column Store Index در SQL Server 2012

 Column Store Index یکی از ویژگیهای جدید SQL Server 2012 می باشد، که کارایی Query های قایل اجرا روی دیتابیس‌های با حجم داده ای بسیار بالا را (که اصطلاحا به آنها Data Warehouse یا انبار داده گویند)، چندین برابر بهبود بخشیده است

 قبل از توضیح در مورد Column Store مختصری در مورد نحوه ذخیره سازی داده‌ها در SQL Server می پردازیم. می‌توان گفت در SQL Server دو روش ذخیره سازی وجود دارد،یکی بصورت ردیفی که اصطلاحا به آن  Row Storeیا  Row-Wise گویند، و دیگری بصورت ستونی که اصطلاحا به آن Column Store گویند

در روش ذخیره سازی Row Store، مقادیر ستونها در یک سطر بصورت متوالی ذخیره می‌شوند، در این روش ذخیره سازی از ساختار B-Tree یا Heap استفاده می‌شود.

یادآوری: در ساختار B-Tree، یک گره Root وجود دارد، و گره بعد از Root گره ای است که آدرس گره راست بعدی و آدرس گره چپ بعدی را در خود نگه می‌دارد.

شکل زیر نمای یک درخت B-Tree می‌باشد:

جهت کسب اطلاعات بیشتر درمورد ساختار B-Tree 

یادآوری: وقتی در یک جدول، ایندکسی از نوع Clustered ایجاد نماییم، SQL Server، در ابتدا یک کپی از جدول ایجاد و داده‌های جدول را از نو مرتب می‌نماید، و ساختار صفحه ریشه و دیگر صفحات را ایجاد می‌کند و سپس جدول اصلی را حذف می‌نماید. به جدولی که Clustered Index ندارد، اصطلاحا Heap گویند.

  برخلاف ذخیره سازی Row Store، در ذخیره سازی Column Store، داده‌ها بصورت ستونی ذخیره می‌شوند،در این روش داده ها، فشرده سازی می‌شوند و اینکار باعث می‌شود،در زمان درخواست یک Query، نیاز به Disk I/o به حداقل برسد، در نتیجه، زمان و سرعت پاسخگویی به پرس و جو‌ها بسیار افزایش می‌یابد.

شکل زیر نحوه ذخیره سازی داده ها،بصورت Row Store را نمایش می‌دهد:

  شکل بالا ذخیره سازی داده ها، در ساختار B-Tree یا Heap را نمایش می‌دهد، در شکل فوق یک جدول چهار ستونی با N سطر (Row) در نظر گرفته شده است.بطوریکه ستونهای هر Row بطور متوالی در یک صفحه (Page) یکسان ذخیره می‌شوند.

 شکل زیر نحوه ذخیره سازی داده ها،بصورت Column Store را نمایش می‌دهد:

  مطابق شکل،ستونهای مربوط به هر Row،همگی در یک صفحه (Page) یکسان ذخیره شده اند. به عنوان مثال ستون C1 که مربوط به سطر اول (Row1) می‌باشد، با ستون C1 که مربوط به سطر دوم (Row2) می‌باشد، در یک ستون و در یک صفحه (Page1) ذخیره شده اند، و الی آخر ...

   سئوال: یکبار دیگر به هردو شکل با دقت نگاهی بیاندازید، عمده تفاوت آنها در چیست؟

   جواب: درست حدس زدید، تفاوت بارز بین دو روش Column Store و Row Store در نحوه ذخیره سازی داده‌ها می‌باشد. بطور مثال، فرض کنید،در روش ذخیره سازی Row Store، به دنبال مقادیری از ستون C2 می‌باشید، SQL Server می‌بایست کل رکورد‌های جدول (منظور همه Row‌ها در همه Page ها)را Scan نماید، تا مقادیر مربوط به ستون C2 را بدست آورد.درحالیکه در روش ذخیره سازی Column Store، جهت یافتن مقادیر ستون C2، نیازی به Scan نمودن کل جدول نیست،بلکه SQL Server فقط به Scan نمودن ستون دوم (C2) یا Page2 بسنده می‌نماید.همین امر باعث افزایش چندین برابری، زمان پاسخگویی به هر Query می‌شود.

  سئوال: در روش ذخیره سازی Column Store، چگونه مصرف حافظه بهینه می‌شود؟

  جواب: واضح است،  که در روش SQL Server، Row Store مجبور است، برای بدست آوردن داده‌های مورد نظرتان،کل اطلاعات جدول را وارد حافظه نماید(اطلاعات اضافه ای که به هیچ وجه بدرد، نتیجه پرس و جوی شما نمی‌خورد)، و شروع به Scan داده‌های مد نظر شما می‌نماید.بطوریکه در روش SQL Server، Column Store، فقط ستون داده‌های مورد پرس و جو را در حافظه قرار می‌دهد.(در واقع فقط داده هایی را در حافظه قرار می‌دهد، که شما به آن نیاز دارید)،بنابراین،طبیعی است که در روش Column Store مقدار حافظه کمتری نسبت به روش Row Store در هنگام اجرای Query استفاده می‌شود. به عبارت دیگر می‌توان گفت که در روش Column Store به دلیل، به حداقل رساندن استفاده از Disk I/o سرعت و زمان پاسخگویی به پرس و جو‌ها چندین برابر می‌شود.

  برای درک بیشتر Row Store و Column Store مثالی می‌زنیم:

   فرض کنید،قصد بدست آوردن ستونهای C1 و C2 از جدول A را داریم، بنابراین خواهیم داشت:

Select C1, C2 from A

روش Row Store:

    در این روش همه صفحات دیسک (مربوط به جدول A) درون حافظه قرار داده می‌شود، یعنی علاوه بر ستونهای C1 و C2، اطلاعات مربوط به ستونهای C3 و C4 نیز درون حافظه قرار می‌گیرد،بطوریکه مقادیر ستونهای C3 و C4 به هیچ وجه مورد قبول ما نیست، و در خروجی پرس و جوی ما تاثیری ندارد، و فقط بی جهت حافظه اشغال می‌نماید.

روش Column Store:

  در این روش فقط صفحات مروبط به ستون C1 و C2 در حافظه قرار می‌گیرد.(منظور Page1 و Page2 می‌باشد) بنابراین فقط اطلاعات مورد نیاز در خروجی، در حافظه قرار می‌گیرد.

  •  از دیگر مزایای استفاده از روش Column Store، فشرده سازی داده می‌باشد،برای درک بیشتر توضیح می‌دهم:
      همانطور که در اوایل مطلبم به عرض رساندم، در روش Row Store ، داده‌ها در یک سطر و در یک Page ذخیره می‌شوند، بنابراین امکان وجود داده‌های تکراری در یک سطر به حداقل می‌رسد، چرا که، اگر فرض کنیم چهار ستون  به نام‌های ID،FirstName،LastName و City، داشته باشیم،در آن صورت بطور حتم،در یک سطر، داده تکراری وجود نخواهد داشت، اما ممکن است در تعداد سطرهای زیاد داده‌های تکراری مانند Firstname یا City و غیرو بوجود بیاید، این موضوع را بیان کردم، چون می‌خواستم عنوان کنم،بسیاری از الگوریتم‌های فشرده سازی از الگوی تکراری بودن داده، جهت فشرده سازی داده‌ها استفاده می‌کنند، به همین جهت فشرده سازی در روش Row Store به حداقل می‌رسد و فضای اشغال شده در حافظه دراین روش بسیار زیاد خواهد بود. اما در روش Column Store ، امکان تکراری بودن مقادیر یک ستون بسیار زیاد  است، بطور مثال ممکن است تعداد افرادی را که نام شهر  آنها "تهران" باشد مثلا 20 بار تکرار شده باشد، و چون در روش Column Store، ستون‌ها در یک Page ذخیره می‌شوند، بنابراین امکان استفاده از الگوریتمهای فشرده سازی در این روش بسیار بالا می‌باشد، در نتیجه مقدار فضایی را که در حافظه یا دیسک سخت توسط این روش اشغال می‌شود، بسیار کمتر از روش Row Store است.

چه موقع می‌توانیم از Column Store استفاده نماییم:

   در تعریف Column Store گفته بودم، روش فوق، جهت بهبود بخشیدن به زمان و سرعت پاسخگویی به Query‌های اجرا شده روی دیتابیس‌های با حجم داده ای بسیار بالا(Data Warehouse ) می‌باشد، به بیان ساده‌تر Column Store را روی دیتابیس‌های offline یا دیتابیسهایی که صرفا جهت گزارش گیری مورد استفاده قرار می‌گیرند، تنظیم می‌نمایند.در واقع با تنظیم Column Store Index روی Database‌های بزرگ مانند Database‌های بانک‌ها که حجم داده ای میلیونی در جداول آنها وجود دارد، سرعت پاسخگویی Query ها، چندین برابر افزایش می‌یابد.

  •      در یک جدول می‌توانید، هم Column Store Index داشته باشید و هم یک Row Store Index (منظور یک  Clustered Index می باشد)
  • Syntax برای ایجاد  Column Store Index به شرح ذیل می‌باشد:
CREATE [ NONCLUSTERED ] COLUMNSTORE INDEX index_name 
    ON <object> ( column  [ ,...n ] )
    [ WITH ( <column_index_option> [ ,...n ] ) ]
    [ ON {
           { partition_scheme_name ( column_name ) } 
           | filegroup_name 
           | "default" 
         }
    ]
[ ; ]

<object> ::=
{
    [database_name. [schema_name ] . | schema_name . ]
     table_name
{

<column_index_option> ::=
{
      DROP_EXISTING = { ON | OFF }
    | MAXDOP = max_degree_of_parallelism
 }
  • یک Column Store Index می‌بایست از نوع NONCLUSTERED باشد.
مثال از یک Column Store Index :
CREATE NONCLUSTERED COLUMNSTORE INDEX [IX_MyFirstName_ColumnStore]
ON [Test]
(Firstname)
در قطعه کد بالا، یک Column Store Index به نام Ix_MyFirstname_ColumnStore روی فیلد Firstname از جدول Test ایجاد شده است.
محدودیت‌های استفاده از Column Store Index به اختصار به شرح ذیل می‌باشد:
  • زمانی که در یک جدول، یک Column Store Index ایجاد نماییم، جدول ما  در حالت Read-only قرار می‌گیرد، بطوریکه از آن پس  اختیار Delete،Update و Insert روی جدول فوق را نخواهیم داشت. برای اینکه بتوانید عملیات Insert، Update یا Delete را انجام دهید، میبایست Column Store Index جدول مربوطه را Disable نمایید، و برای فعال نمودن Column Store Index، می‌بایست آن را Rebuild نمایید، با کلیک راست روی ایندکس ایجاد شده در SQL Server2012 موارد Disable و Rebuild قابل مشاهده می‌باشد.

یا بوسیله Script‌های زیر می‌توانید، عملیات Disable یا Rebuild را روی Column Store Index انجام دهید:
ALTER INDEX [IX_MyFirstName_ColumnStore] ON [Test] DISABLE

ALTER INDEX [IX_MyFirstName_ColumnStore] ON [Test] Rebuild
  • بیشتر از یک Column Store Index نمی‌توانید روی یک جدول ایجاد نمایید.
  • در صورتی که تمایل داشته باشید بوسیله Alter ، نوع فیلدی (Type)، را که Column Store Index روی آنها اعمال گردیده است، تغییر دهید، در ابتدا می‌بایست Column Store Index، خود را Drop یا حذف نمایید، سپس عملیات Alter را اعمال کنید، در غیر اینصورت با خطای SQL Server مواجه می‌شوید.
  • یک Column Store Index می‌تواند روی 1024 ستون در یک جدول اعمال گردد.
  • یک Column Store Index  نمی توانند، Unique باشد و نمی‌توان از آن به عنوان Primary Key یا Foreign Key استفاده نمود.
یاد آوری: با توجه به مزایای استفاده از Column Store Index، باید بگویم که در حجم‌های داده ای کم استفاده از Row Store Index بهتر می‌باشد. پیشنهاد مایکروسافت برای استفاده از Column Store Index برای دیتابیس‌های با حجم داده ای بسیار بالا می‌باشد.
موفق باشید
منابع:

نظرات اشتراک‌ها
دوراهی انتخاب NHibernate و Entityframework
استفاده از NH در مقابل EF Code first سورس باز اشتباه است؛ به دلایل زیر:
- توهم پشتیبانی از بانک‌های اطلاعاتی مختلف توسط NH . به شخصه با حداقل یک مورد نیم بند آن سروکار داشتم: SQL-CE. تقریبا بیشتر از نیمی از توانایی‌های این بانک اطلاعاتی در NH لحاظ نشده و حتی یک کوئری ساده از تاریخ تا تاریخ را توسط آن نمی‌توانید تهیه کنید. این مورد برعکس EF Code first است. کامل و بی‌نقص کار می‌کند. کلا تمام محصولات مایکروسافت به همین نحو هستند. اگر عنوان می‌کنند این محصول دو قابلیت دارد، واقعا این دو قابلیت، درست کار می‌کنند. نه اینکه عنوان کنند 100 قابلیت را ارائه می‌دهیم و فقط 10 تای آن کامل پیاده سازی شده باشند.
- تیم مدیریتی به شدت مغرور و ناراحت NH. باز هم برای این تیم ناراحت، جهت تکمیل نقایص کار با SQL-CE بیشتر از یکسال قبل وصله‌ای رو ارسال کردم. تا به امروز حتی یک پاسخ که آیا خوبه، بده ... ارسال نشده. با اکثر همکاری‌ها هم به همین نحو رفتار می‌کنند.
خلاصه حال و هوای یک پروژه سالم سورس باز را ندارد.
- پس از ارائه EF Code first این پروژه تقریبا غیرفعال شده: (^)
- نیم بند بودن پشتیبانی از LINQ. باز هم اگر تصور می‌کنید که راحت می‌تونید مثل EF از کوئری‌های LINQ در اینجا استفاده کنید، سخت در اشتباه هستید.
- دیر به روز شدن کتابخانه‌های جانبی آن. این مساله هم به مدیریت بد پروژه NH بر می‌گردد. شاید بیشتر از 10 مورد افزونه برای NH هست، مانند کش و اعتبار سنجی و غیره. اما ... صاحبان آن مشخص نیستند! امروز NH3 ارائه می‌شود، سه ماه بعد کتابخانه اعتبارسنجی متناظر با آن. تیم NH هم حاضر نشده تمام این‌ها رو کنار هم قرار بده و یک کار یکپارچه رو ارائه کنه. NH اعتبار خودش رو از این افزونه‌های موجود در NH Contrib کسب می‌کنه، اما حاضر نیستند مدیریت و نگهداری یکپارچه آن‌ها را قبول کنند.
- ناسازگاری با اکوسیستم دات نت. اگر از NH استفاده کنید مدام در حال جنگ با دات نت هستید. مثلا سیستم اعتبار سنجی EF با سیستم اعتبار سنجی سمت کلاینت و سرور MVC یکپارچه است. با NH اینطور نیست و از این نوع مثال‌ها زیاد است. همین مساله حجم کاری شما را چندبرابر می‌کند.
- طراحی زمخت NH در مقابل طراحی روان EF. برای مثال در EF Code first شما به ندرت نیاز خواهید داشت که نگاشت‌ها را تعریف یا حتی سفارشی سازی کنید. یک سری پیش فرض بسیار عالی در آن به صورت توکار (و نه به شکل افزونه) وجود دارد که حجم کاری شما را به شدت کاهش می‌دهند. در NH کتابخانه fluent nh سعی کرده که اینکار را انجام دهد اما جالب اینجا است که این کتابخانه از طرف تیم اصلی NH اصلا تحویل گرفته نشده و ... دست آخر هم یک روش دیگر را برای نوشتن نگاشت‌ها با کد تهیه کردند.
- مستندات NH کامل نیست. برای مثال شاید یک سری بلاگ‌های متفرقه را پیدا کنید که در مورد روش تهیه نگاشت‌ها با کد مطلب نوشته باشند ... نه توسط کسانی که این کتابخانه را تهیه کرده‌اند! این روند رو مقایسه کنید با وبلاگ EF مثلا : (^) این بلاگ تا این حد کامل است که مرجع بسیاری از مطالب آموزشی و کتاب‌های مرتبط با EF می‌باشد.
- سیستم migration موجود در EF Code first نسبت به نمونه NH بسیار کاملتر است؛ با قابلیت سفارشی سازی، مقایسه هش مدل‌ها با جداول جهت جلوگیری از تداخلات و اشتباهات، تولید اسکریپت آپدیت بانک اطلاعاتی و غیره.

یک زمانی بود دات نت ORM قابل ملاحظه‌ای نداشت. زمان دات نت2. در آن موقع NH حرف برای گفتن داشت اما ... نه الان.
نظرات مطالب
شروع کار با Apache Cordova در ویژوال استودیو #2

سلام مرسی بابت مطلبتون لطفاً راهنماییم کنین
مسیری هم که توی path دادم به این شکل هست
C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\ManagementStudio\;C:\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Skype\Phone\;C:\Program Files (x86)\CodeSmith\v5.2\;C:\Program Files (x86)\nodejs\;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\;%JAVA_HOME%\bin;%ADT_HOME%\tools;%ADT_HOME%\platform-tools;%ANT_HOME%\bin;%GIT_HOME%\cmd;C:\Program Files (x86)\nodejs\;%JAVA_HOME%\bin;%ANT_HOME%\bin;%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools;E:\Android Softwares\android-sdk Complete\android-sdk;

مسیر sdk هم اینجا هست
E:\Android Softwares\android-sdk Complete\android-sdk

 

در ضمن  path قبلی هم این بود

C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\ManagementStudio\;C:\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Skype\Phone\;C:\Program Files (x86)\CodeSmith\v5.2\;C:\Program Files (x86)\nodejs\;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\;%JAVA_HOME%\bin;%ADT_HOME%\tools;%ADT_HOME%\platform-tools;%ANT_HOME%\bin;%GIT_HOME%\cmd


اما ارور زیر همچنان بر قرار است

 
نظرات مطالب
اتصال SQL Server به MySQL
دو نکته تکمیلی:
- برای انتقال کل اطلاعات یک جدول از SQL Server به MySQL لینک شده با اجرای فقط یک کوئری:

insert into openquery(mysql, 'select f1,f2 from testdb.testtable') select f1,f2 from testdb.dbo.myTable

در اینجا testdb.testtable مربوط به طرف MySQL است و testdb.dbo.myTable مربوط به طرف SQL Server .

- کوئری گرفتن از Linked server به صورت زیر هم می‌تواند باشد (بر اساس دیتابیس پیش فرض ذکر شده در پروایدر استرینگ):
SELECT * FROM mysql...testtable
مطالب
گزارشگیری از تاریخچه‌ی پشتیبان‌گیری‌ها در اس کیوال سرور

آیا می‌دانید آخرین باری که از یک دیتابیس مفروض بک‌آپ گرفته شده، چه زمانی بوده است؟ (یا اینکه اصلا چه اهمیتی داره؟!)

USE master;
SELECT B.name AS Database_Name,
ISNULL(STR(ABS(DATEDIFF(day, GetDate(),
MAX(Backup_finish_date)))), 'NEVER') AS DaysSinceLastBackup,
ISNULL(CONVERT(char(10), MAX(backup_finish_date), 101), 'NEVER') AS
LastBackupDate
FROM master.dbo.sysdatabases B
LEFT OUTER JOIN msdb.dbo.backupset A
ON A.database_name = B.name
AND A.type = 'D'
GROUP BY
B.Name
ORDER BY
B.name


همانطور که مطلع هستید در SQL Server 2008 امکان فشرده سازی خودکار بک آپ‌ها هم فراهم شده است. با استفاده از اسکریپت زیر می‌توان از درصد فشرده سازی بک‌آپ‌ها گزارش گرفت:
SELECT bs.server_name,
bs.database_name AS 'Database Name',
CONVERT (BIGINT, bs.backup_size / 1048576 ) AS
'Uncompressed Backup Size (MB)',
CONVERT (BIGINT, bs.compressed_backup_size / 1048576 ) AS
'Compressed Backup Size (MB)',
CONVERT (NUMERIC (20,2), (CONVERT (FLOAT, bs.backup_size) /
CONVERT (FLOAT, bs.compressed_backup_size))) AS 'Compression Ratio',
DATEDIFF (SECOND, bs.backup_start_date, bs.backup_finish_date) AS
'Backup Elapsed Time (sec)',
bs.backup_finish_date AS 'Backup Finish Date'
FROM msdb.dbo.backupset AS bs
WHERE DATEDIFF (SECOND, bs.backup_start_date, bs.backup_finish_date) > 0
AND bs.backup_size > 0
AND bs.type = 'D' -- Change to L if you want Log backups
ORDER BY
bs.backup_finish_date DESC




برای فعال سازی گزینه فشرده سازی بک‌آپ‌ها با استفاده از دستورات T-SQL می‌توان به صورت زیر عمل کرد (در SQL server 2008):
USE master;
EXEC sp_configure 'backup compression default', '1';
RECONFIGURE WITH OVERRIDE;



ماخذ مورد استفاده:
http://www.sqlservercentral.com

مطالب
توزیع یک اپلیکیشن ASP.NET MVC 5 روی Windows Azure
این مقاله به شما نشان می‌دهد چگونه یک اپلیکیشن وب ASP.NET MVC 5 بسازید که کاربران را قادر می‌سازد با اطلاعات Facebook یا Google احراز هویت شده و به سایت وارد شوند. همچنین این اپلیکیشن را روی Windows Azure توزیع (Deploy) خواهید کرد.
می توانید بصورت رایگان یک حساب کاربری Windows Azure بسازید. اگر هم Visual Studio 2013 را ندارید، بسته SDK بصورت خودکار Visual Studio 2013 for Web را نصب می‌کند. پس از آن می‌توانید به توسعه رایگان اپلیکیشن‌های Azure بپردازید، اگر می‌خواهید از Visual Studio 2012 استفاده کنید به این مقاله مراجعه کنید. این مقاله نسبت به لینک مذکور بسیار ساده‌تر است.
این مقاله فرض را بر این می‌گذارد که شما هیچ تجربه ای در کار با Windows Azure ندارید. در انتهای این مقاله شما یک اپلیکیشن مبتنی بر داده (data-driven) و امن خواهید داشت که در فضای رایانش ابری اجرا می‌شود.
چیزی که شما یاد می‌گیرید:
  • چطور یک اپلیکیشن وب ASP.NET MVC 5 بسازید و آن را روی یک وب سایت Windows Azure منتشر کنید.
  • چگونه از OAuth، OpenID و سیستم عضویت ASP.NET برای ایمن سازی اپلیکیشن خود استفاده کنید.
  • چگونه از API جدید سیستم عضویت برای مدیریت اعضا و نقش‌ها استفاده کنید.
  • چگونه از یک دیتابیس SQL برای ذخیره داده‌ها در Windows Azure استفاده کنید.
شما یک اپلیکیشن مدیریت تماس (Contact Manager) ساده خواهید نوشت که بر پایه ASP.NET MVC 5 بوده و از Entity Framework برای دسترسی داده استفاده می‌کند. تصویر زیر صفحه ورود نهایی اپلیکیشن را نشان می‌دهد.

توجه: برای تمام کردن این مقاله به یک حساب کاربری Windows Azure نیاز دارید، که بصورت رایگان می‌توانید آن را بسازید. برای اطلاعات بیشتر به Windows Azure Free Trial مراجعه کنید.

در این مقاله:

  • برپایی محیط توسعه (development environment)
  • برپایی محیط Windows Azure
  • ایجاد یک اپلیکیشن ASP.NET MVC 5
  • توزیع اپلیکیشن روی Windows Azure
  • افزودن یک دیتابیس به اپلیکیشن
  • افزودن یک OAuth Provider
  • استفاده از Membership API
  • توزیع اپلیکیشن روی Windows Azure
  • قدم‌های بعدی


برپایی محیط توسعه

برای شروع Windows Azure SDK for .NET را نصب کنید. برای اطلاعات بیشتر به Windows Azure SDK for Visual Studio 2013 مراجعه کنید. بسته به اینکه کدام یک از وابستگی‌ها را روی سیستم خود دارید، پروسه نصب می‌تواند از چند دقیقه تا نزدیک دو ساعت طول بکشد. توسط Web Platform می‌توانید تمام نیازمندی‌های خود را نصب کنید.

هنگامی که این مرحله با موفقیت به اتمام رسید، تمام ابزار لازم برای شروع به کار را در اختیار دارید.


برپایی محیط Windows Azure

در قدم بعدی باید یک وب سایت Windows Azure و یک دیتابیس بسازیم.
ایجاد یک وب سایت و دیتابیس در Windows Azure

وب سایت Windows Azure شما در یک محیط اشتراکی (shared) میزبانی می‌شود، و این بدین معنا است که وب سایت‌های شما روی ماشین‌های مجازی (virtual machines) اجرا می‌شوند که با مشتریان دیگر Windows Azure به اشتراک گذاشته شده اند. یک محیط میزبانی اشتراکی گزینه ای کم هزینه برای شروع کار با رایانش‌های ابری است. اگر در آینده ترافیک وب سایت شما رشد چشم گیری داشته باشد، می‌توانید اپلیکیشن خود را طوری توسعه دهید که به نیازهای جدید پاسخگو باشد و آن را روی یک ماشین مجازی اختصاصی (dedicated VMs) میزبانی کنید. اگر معماری پیچیده‌تری نیاز دارید، می‌توانید به یک سرویس Windows Azure Cloud مهاجرت کنید. سرویس‌های ابری روی ماشین‌های مجازی اختصاصی اجرا می‌شوند که شما می‌توانید تنظیمات آنها را بر اساس نیازهای خود پیکربندی کنید.
Windows Azure SQL Database یک سرویس دیتابیس رابطه ای (relational) و مبتنی بر Cloud است که بر اساس تکنولوژی‌های SQL Server ساخته شده. ابزار و اپلیکیشن هایی که با SQL Server کار می‌کنند با SQL Database نیز می‌توانند کار کنند.

  • روی Web Site  و سپس Custom Create  کلیک کنید.

  • در مرحله Create Web Site  در قسمت URL  یک رشته وارد کنید که آدرسی منحصر بفرد برای اپلیکیشن شما خواهد بود. آدرس کامل وب سایت شما، ترکیبی از مقدار این فیلد و مقدار روبروی آن است.

  • در لیست Database گزینه Create  a free 20 MB SQL Database  را انتخاب کنید.
  • در لیست Region  همان مقداری را انتخاب کنید که برای وب سایت تان انتخاب کرده اید. تنظیمات این قسمت مشخص می‌کند که ماشین مجازی (VM) شما در کدام مرکز داده (data center) خواهد بود.
  • در قسمت DB Connection String Name  مقدار پیش فرض DefaultConnection  را بپذیرید.
  • دکمه فلش پایین صفحه را کلیک کنید تا به مرحله بعد، یعنی مرحله Specify Database Settings  بروید.
  • در قسمت Name  مقدار ContactDB  را وارد کنید (تصویر زیر).
  • در قسمت Server  گزینه New SQL Database Server  را انتخاب کنید. اگر قبلا دیتابیس ساخته اید می‌توانید آن را از کنترل dropdown انتخاب کنید.
  • مقدار قسمت Region  را به همان مقداری که برای ایجاد وب سایت تان تنظیم کرده اید تغییر دهید.
  • یک Login Name  و Password  مدیر (administrator) وارد کنید. اگر گزینه  New SQL Database server را انتخاب کرده اید، چنین کاربری وجود ندارد و در واقع اطلاعات یک حساب کاربری جدید را وارد می‌کنید تا بعدا هنگام دسترسی به دیتابیس از آن استفاده کنید. اگر دیتابیس دیگری را از لیست انتخاب کرده باشید، اطلاعات یک حساب کاربری موجود از شما دریافت خواهد شد. در مثال این مقاله ما گزینه Advanced  را رها می‌کنیم. همچنین در نظر داشته باشید که برای دیتابیس‌های رایگان تنها از یک Collation می‌توانید استفاده کنید.

دکمه تایید پایین صفحه را کلیک کنید تا مراحل تمام شود.

تصویر زیر استفاده از یک SQL Server و حساب کاربری موجود (existing) را نشان می‌دهد.

پرتال مدیریتی پس از اتمام مراحل، به صفحه وب سایت‌ها باز می‌گردد. ستون Status نشان می‌دهد که سایت شما در حال ساخته شدن است. پس از مدتی (معمولا کمتر از یک دقیقه) این ستون نشان می‌دهد که سایت شما با موفقیت ایجاد شده. در منوی پیمایش سمت چپ، تعداد سایت هایی که در اکانت خود دارید در کنار آیکون Web Sites نمایش داده شده است، تعداد دیتابیس‌ها نیز در کنار آیکون SQL Databases نمایش داده می‌شود.


یک اپلیکیشن ASP.NET MVC 5 بسازید

شما یک وب سایت Windows Azure ساختید، اما هنوز هیچ محتوایی در آن وجود ندارد. قدم بعدی ایجاد یک اپلیکیشن وب در ویژوال استودیو و انتشار آن است. ابتدا یک پروژه جدید بسازید.

نوع پروژه را ASP.NET Web Application انتخاب کنید.

نکته: در تصویر بالا نام پروژه "MyExample" است اما حتما نام پروژه خود را به "ContactManager" تغییر دهید. قطعه کدهایی که در ادامه مقاله خواهید دید نام پروژه را ContactManager فرض می‌کنند.

در دیالوگ جدید ASP.NET نوع اپلیکیشن را MVC انتخاب کنید و دکمه Change Authentication را کلیک کنید.

گزینه پیش فرض Individual User Accounts را بپذیرید. برای اطلاعات بیشتر درباره متدهای دیگر احراز هویت به این لینک مراجعه کنید. دکمه‌های OK را کلیک کنید تا تمام مراحل تمام شوند.


تنظیم تیتر و پاورقی سایت

  • فایل Layout.cshtml_   را باز کنید. دو نمونه از متن "My ASP.NET MVC Application" را با عبارت "Contact Manager" جایگزین کنید.
  • عبارت "Application name" را هم با "CM Demo" جایگزین کنید.
اولین Action Link را ویرایش کنید و مقدار Home را با Cm جایگزین کنید تا از CmController استفاده کند.


اپلیکیشن را بصورت محلی اجرا کنید

اپلیکیشن را با Ctrl + F5 اجرا کنید. صفحه اصلی باید در مرورگر پیش فرض باز شود.

اپلیکیشن شما فعلا آماده است و می‌توانید آن را روی Windows Azure توزیع کنید. بعدا دیتابیس و دسترسی داده نیز اضافه خواهد شد.


اپلیکیشن را روی Windows Azure منتشر کنید

در ویژوال استودیو روی نام پروژه کلیک راست کنید و گزینه Publish را انتخاب کنید. ویزارد Publish Web باز می‌شود.
در قسمت Profile روی Import کلیک کنید.

حال دیالوگ Import Publish Profile نمایش داده می‌شود.

یکی از متدهای زیر را استفاده کنید تا ویژوال استودیو بتواند به اکانت Windows Azure شما متصل شود.

  • روی Sign In کلیک کنید تا با وارد کردن اطلاعات حساب کاربری وارد Windows Azure شوید.
این روش ساده‌تر و سریع‌تر است، اما اگر از آن استفاده کنید دیگر قادر به مشاهده Windows Azure SQL Database یا Mobile Services در پنجره Server Explorer نخواهید بود.
  • روی Manage subscriptions کلیک کنید تا یک management certificate نصب کنید، که دسترسی به حساب کاربری شما را ممکن می‌سازد.
در دیالوگ باکس Manage Windows Azure Subscriptions به قسمت Certificates بروید. سپس Import را کلیک کنید. مراحل را دنبال کنید تا یک فایل subscription را بصورت دانلود دریافت کنید (فایل‌های publishsettings.) که اطلاعات اکانت Windows Azure شما را دارد.

نکته امنیتی: این فایل تنظیمات را بیرون از پوشه‌های سورس کد خود دانلود کنید، مثلا پوشه Downloads. پس از اتمام عملیات Import هم این فایل را حذف کنید. کاربر مخربی که به این فایل دسترسی پیدا کند قادر خواهد بود تا سرویس‌های Windows Azure شما را کاملا کنترل کند.
برای اطلاعات بیشتر به How to Connect to Windows Azure from Visual Studio مراجعه کنید.
در دیالوگ باکس Import Publish Profile وب سایت خود را از لیست انتخاب کنید و OK را کلیک کنید.

در دیالوگ باکس Publish Web روی Publish کلیک کنید.

اپلیکیشن شما حالا در فضای ابری اجرا می‌شود. دفعه بعد که اپلیکیشن را منتشر کنید تنها فایل‌های تغییر کرده (یا جدید) آپلود خواهند شد.


یک دیتابیس به اپلیکیشن اضافه کنید

در مرحله بعد یک دیتابیس خواهیم ساخت تا اپلیکیشن ما بتواند اطلاعات را نمایش دهد و ویرایش کند. برای ایجاد دیتابیس و دسترسی به داده‌ها از Entity Framework استفاده خواهیم کرد.


کلاس‌های مدل Contacts را اضافه کنید

در پوشه Models پروژه یک کلاس جدید ایجاد کنید.

نام کلاس را به Contact.cs تغییر دهید و دکمه Add را کلیک کنید.

کد فایل Contact.cs را با قطعه کد زیر مطابقت دهید.

using System.ComponentModel.DataAnnotations;
using System.Globalization;
namespace ContactManager.Models
{
    public class Contact
    {
        public int ContactId { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Zip { get; set; }
        [DataType(DataType.EmailAddress)]
        public string Email { get; set; }
    }
}

این کلاس موجودیت Contact را در دیتابیس معرفی می‌کند. داده هایی که می‌خواهیم برای هر رکورد ذخیره کنیم تعریف شده اند، بعلاوه یک فیلد Primary Key که دیتابیس به آن نیاز دارد.


یک کنترلر و نما برای داده‌ها اضافه کنید

ابتدا پروژه را Build کنید (Ctrl + Shift+ B). این کار را باید پیش از استفاده از مکانیزم Scaffolding انجام دهید.
یک کنترلر جدید به پوشه Controllers اضافه کنید.

در دیالوگ باکس Add Scaffold گزینه MVC 5 Controller with views, using EF را انتخاب کنید.

در دیالوگ Add Controller نام "CmController" را برای کنترلر وارد کنید. (تصویر زیر.)

در لیست Model گزینه (Contact (ContactManager.Models را انتخاب کنید.

در قسمت Data context class گزینه (ApplicationDbContext (ContactManager.Models را انتخاب کنید. این ApplicationDbContext هم برای اطلاعات سیستم عضویت و هم برای داده‌های Contacts استفاده خواهد شد.

روی Add کلیک کنید. ویژوال استودیو بصورت خودکار با استفاده از Scaffolding متدها و View‌های لازم برای عملیات CRUD را فراهم می‌کند، که همگی از مدل Contact استفاده می‌کنند.


فعالسازی مهاجرت ها، ایجاد دیتابیس، افزودن داده نمونه و یک راه انداز

مرحله بعدی فعال کردن قابلیت Code First Migrations است تا دیتابیس را بر اساس الگویی که تعریف کرده اید بسازد.
از منوی Tools گزینه Library Package Manager و سپس Package Manager Console را انتخاب کنید.

در پنجره باز شده فرمان زیر را وارد کنید.

enable-migrations

فرمان enable-migrations یک پوشه با نام Migrations می سازد و فایلی با نام Configuration.cs را به آن اضافه می‌کند. با استفاده از این کلاس می‌توانید داده‌های اولیه دیتابیس را وارد کنید و مهاجرت‌ها را نیز پیکربندی کنید.

در پنجره Package Manager Console فرمان زیر را وارد کنید.

add-migration Initial

فرمان add-migration initial فایلی با نام data_stamp> initial> ساخته و آن را در پوشه Migrations ذخیره می‌کند. در این مرحله دیتابیس شما ایجاد می‌شود. در این فرمان، مقدار initial اختیاری است و صرفا برای نامگذاری فایل مهاجرت استفاده شده. فایل‌های جدید را می‌توانید در Solution Explorer مشاهده کنید.

در کلاس Initial متد Up جدول Contacts را می‌سازد. و متد Down (هنگامی که می‌خواهید به وضعیت قبلی بازگردید) آن را drop می‌کند.

حال فایل Migrations/Configuration.cs را باز کنید. فضای نام زیر را اضافه کنید.

using ContactManager.Models;

حال متد Seed را با قطعه کد زیر جایگزین کنید.

protected override void Seed(ContactManager.Models.ApplicationDbContext context)
{
    context.Contacts.AddOrUpdate(p => p.Name,
       new Contact
       {
           Name = "Debra Garcia",
           Address = "1234 Main St",
           City = "Redmond",
           State = "WA",
           Zip = "10999",
           Email = "debra@example.com",
       },
        new Contact
        {
            Name = "Thorsten Weinrich",
            Address = "5678 1st Ave W",
            City = "Redmond",
            State = "WA",
            Zip = "10999",
            Email = "thorsten@example.com",
        },
        new Contact
        {
            Name = "Yuhong Li",
            Address = "9012 State st",
            City = "Redmond",
            State = "WA",
            Zip = "10999",
            Email = "yuhong@example.com",
        },
        new Contact
        {
            Name = "Jon Orton",
            Address = "3456 Maple St",
            City = "Redmond",
            State = "WA",
            Zip = "10999",
            Email = "jon@example.com",
        },
        new Contact
        {
            Name = "Diliana Alexieva-Bosseva",
            Address = "7890 2nd Ave E",
            City = "Redmond",
            State = "WA",
            Zip = "10999",
            Email = "diliana@example.com",
        }
        );
}

این متد دیتابیس را Seed می‌کند، یعنی داده‌های پیش فرض و اولیه دیتابیس را تعریف می‌کند. برای اطلاعات بیشتر به Seeding and Debugging Entity Framework (EF) DBs مراجعه کنید.

در پنجره Package Manager Console فرمان زیر را وارد کنید.

update-database

فرمان update-database مهاجرت نخست را اجرا می‌کند، که دیتابیس را می‌سازد. بصورت پیش فرض این یک دیتابیس SQL Server Express LocalDB است.

حال پروژه را با CTRL + F5 اجرا کنید.

همانطور که مشاهده می‌کنید، اپلیکیشن داده‌های اولیه (Seed) را نمایش می‌دهد، و لینک هایی هم برای ویرایش، حذف و مشاهده جزئیات رکورد‌ها فراهم می‌کند. می‌توانید داده‌ها را مشاهده کنید، رکورد جدید ثبت کنید و یا داده‌های قبلی را ویرایش و حذف کنید.


یک تامین کننده OAuth2 و OpenID اضافه کنید

OAuth یک پروتکل باز است که امکان authorization امن توسط یک متد استاندارد را فراهم می‌کند. این پروتکل می‌تواند در اپلیکیشن‌های وب، موبایل و دسکتاپ استفاده شود. قالب پروژه ASP.NET MVC internet از OAuth و OpenID استفاده می‌کند تا فیسبوک، توییتر، گوگل و حساب‌های کاربری مایکروسافت را بعنوان تامین کنندگان خارجی تعریف کند. به سادگی می‌توانید قطعه کدی را ویرایش کنید و از تامین کننده احراز هویت مورد نظرتان استفاده کنید. مراحلی که برای اضافه کردن این تامین کنندگان باید دنبال کنید، بسیار مشابه همین مراحلی است که در این مقاله دنبال خواهید کرد. برای اطلاعات بیشتر درباره نحوه استفاده از فیسبوک بعنوان یک تامین کننده احراز هویت به Create an ASP.NET MVC 5 App with Facebook and Google OAuth2 and OpenID Sign-on مراجعه کنید.
علاوه بر احراز هویت، اپلیکیشن ما از نقش‌ها (roles) نیز استفاده خواهد کرد تا از authorization پشتیبانی کند. تنها کاربرانی که به نقش canEdit تعلق داشته باشند قادر به ویرایش اطلاعات خواهند بود (یعنی ایجاد، ویرایش و حذف رکورد ها).
فایل App_Start/Startup.Auth.cs را باز کنید. توضیحات متد app.UseGoogleAuthentication را حذف کنید.
حال اپلیکیشن را اجرا کنید و روی لینک Log In کلیک کنید.
زیر قسمت User another service to log in روی دکمه Google کلیک کنید. اطلاعات کاربری خود را وارد کنید. سپس Accept را کلیک کنید تا به اپلیکیشن خود دسترسی کافی بدهید (برای آدرس ایمیل و اطلاعات پایه).
حال باید به صفحه ثبت نام (Register) هدایت شوید. در این مرحله می‌توانید در صورت لزوم نام کاربری خود را تغییر دهید. نهایتا روی Register کلیک کنید.


استفاده از Membership API

در این قسمت شما یک کاربر محلی و نقش canEdit را به دیتابیس عضویت اضافه می‌کنید. تنها کاربرانی که به این نقش تعلق دارند قادر به ویرایش داده‌ها خواهند بود. یکی از بهترین تمرین‌ها (best practice) نام گذاری نقش‌ها بر اساس عملیاتی است که می‌توانند اجرا کنند. بنابراین مثلا canEdit نسبت به نقشی با نام admin ترجیح داده می‌شود. هنگامی که اپلیکیشن شما رشد می‌کند و بزرگتر می‌شود، شما می‌توانید نقش‌های جدیدی مانند canDeleteMembers اضافه کنید، بجای آنکه از نام‌های گنگی مانند superAdmin استفاده کنید.
فایل Migrations/Configuration.cs را باز کنید و عبارات زیر را به آن اضافه کنید.
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
متد AddUserAndRole را به این کلاس اضافه کنید.
bool AddUserAndRole(ContactManager.Models.ApplicationDbContext context)
 {
    IdentityResult ir;
    var rm = new RoleManager<IdentityRole>
        (new RoleStore<IdentityRole>(context));
    ir = rm.Create(new IdentityRole("canEdit"));
    var um = new UserManager<ApplicationUser>(
        new UserStore<ApplicationUser>(context));
    var user = new ApplicationUser()
    {
       UserName = "user1",
    };
    ir = um.Create(user, "Passw0rd1");
    if (ir.Succeeded == false)
       return ir.Succeeded;
    ir = um.AddToRole(user.Id, "canEdit");
    return ir.Succeeded;
 }
حالا از متد Seed این متد جدید را فراخوانی کنید.
protected override void Seed(ContactManager.Models.ApplicationDbContext context)
{
    AddUserAndRole(context);
    context.Contacts.AddOrUpdate(p => p.Name,
        // Code removed for brevity
}
این کدها نقش جدیدی با نام canEdit و کاربری با نام user1 می سازد. سپس این کاربر به نقش مذکور اضافه می‌شود.


کدی موقتی برای تخصیص نقش canEdit به کاربران جدید Social Provider ها

در این قسمت شما متد ExternalLoginConfirmation در کنترلر Account را ویرایش خواهید کرد. یا این تغییرات، کاربران جدیدی که توسط OAuth یا OpenID ثبت نام می‌کنند به نقش  canEdit اضافه می‌شوند. تا زمانی که ابزاری برای افزودن و مدیریت نقش‌ها بسازیم، از این کد موقتی استفاده خواهیم کرد. تیم مایکروسافت امیدوار است ابزاری مانند WSAT برای مدیریت کاربران و نقش‌ها در آینده عرضه کند. بعدا در این مقاله با اضافه کردن کاربران به نقش‌ها بصورت دستی از طریق Server Explorer نیز آشنا خواهید شد.
فایل Controllers/AccountController.cs را باز کنید و متد ExternalLoginConfirmation را پیدا کنید.
درست قبل از فراخوانی SignInAsync متد AddToRoleAsync را فراخوانی کنید.
await UserManager.AddToRoleAsync(user.Id, "CanEdit");
کد بالا کاربر ایجاد شده جدید را به نقش canEdit اضافه می‌کند، که به آنها دسترسی به متدهای ویرایش داده را می‌دهد. تصویری از تغییرات کد در زیر آمده است.

در ادامه مقاله اپلیکیشن خود را روی Windows Azure منتشر خواهید کرد و با استفاده از Google و تامین کنندگان دیگر وارد سایت می‌شوید. هر فردی که به آدرس سایت شما دسترسی داشته باشد، و یک حساب کاربری Google هم در اختیار داشته باشد می‌تواند در سایت شما ثبت نام کند و سپس دیتابیس را ویرایش کند. برای جلوگیری از دسترسی دیگران، می‌توانید وب سایت خود را متوقف (stop) کنید.

در پنجره Package Manager Console فرمان زیر را وارد کنید.

Update-Database

فرمان را اجرا کنید تا متد Seed را فراخوانی کند. حال AddUserAndRole شما نیز اجرا می‌شود. تا این مرحله نقش canEdit ساخته شده و کاربر جدیدی با نام user1 ایجاد و به آن افزوده شده است.


محافظت از اپلیکیشن توسط SSL و خاصیت Authorize

در این قسمت شما با استفاده از خاصیت Authorize دسترسی به اکشن متدها را محدود می‌کنید. کاربران ناشناس (Anonymous) تنها قادر به مشاهده متد Index در کنترلر home خواهند بود. کاربرانی که ثبت نام کرده اند به متدهای Index و Details در کنترلر Cm و صفحات About و Contact نیز دسترسی خواهند داشت. همچنین دسترسی به متدهایی که داده‌ها را تغییر می‌دهند تنها برای کاربرانی وجود دارد که در نقش canEdit هستند.

خاصیت Authorize و RequireHttps را به اپلیکیشن اضافه کنید. یک راه دیگر افزودن این خاصیت‌ها به تمام کنترلر‌ها است، اما تجارب امنیتی توصیه می‌کند که این خاصیت‌ها روی کل اپلیکیشن اعمال شوند. با افزودن این خاصیت‌ها بصورت global تمام کنترلر‌ها و اکشن متدهایی که می‌سازید بصورت خودکار محافظت خواهند شد، و دیگر لازم نیست بیاد داشته باشید کدام کنترلر‌ها و متدها را باید ایمن کنید.

برای اطلاعات بیشتر به Securing your ASP.NET MVC App and the new AllowAnonymous Attribute مراجعه کنید.

فایل App_Start/FilterConfig.cs را باز کنید و متد RegisterGlobalFilters را با کد زیر مطابقت دهید.

public static void
RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new System.Web.Mvc.AuthorizeAttribute());
    filters.Add(new RequireHttpsAttribute());
}

خاصیت Authorize در کد بالا از دسترسی کاربران ناشناس به تمام متدهای اپلیکیشن جلوگیری می‌کند. شما برای اعطای دسترسی به متدهایی خاص از خاصیت AllowAnonymous استفاده خواهید کرد. در آخر خاصیت RequireHTTPS باعث می‌شود تا تمام دسترسی‌ها به اپلیکیشن وب شما از طریق HTTPS صورت گیرد.

حالا خاصیت AllowAnonymous را به متد Index  در کنترلر Home اضافه کنید. از این خاصیت برای اعطای دسترسی به تمامی کاربران سایت استفاده کنید. قسمتی از کد کنترلر Home را در زیر می‌بینید.

namespace ContactManager.Controllers
 {
    public class HomeController : Controller
    {
       [AllowAnonymous]
       public ActionResult Index()
       {
          return View();
       }

یک جستجوی عمومی برای عبارت AllowAnonymous انجام دهید. همانطور که مشاهده می‌کنید این خاصیت توسط متدهای ورود و ثبت نام در کنترلر Account نیز استفاده شده است.

در کنترلر CmController خاصیت [("Authorize(Roles="canEdit] را به تمام متدهایی که با داده سر و کار دارند اضافه کنید، به غیر از متدهای Index و Details. قسمتی از کد کامل شده در زیر آمده است.


فعال سازی SSL برای پروژه

در Solution Explorer پروژه خود را انتخاب کنید. سپس کلید F4 را فشار دهید تا دیالوگ خواص (Properties) باز شود. حال مقدار خاصیت SSL Enabled را به true تنظیم کنید. آدرس SSL URL را کپی کنید. این آدرس چیزی شبیه به /https://localhost:44300 خواهد بود.

روی نام پروژه کلیک راست کنید و Properties را انتخاب کنید. در قسمت چپ گزینه Web را انتخاب کنید. حالا مقدار Project Url را به آدرسی که کپی کرده اید تغییر دهید. نهایتا تغییرات را ذخیره کنید و پنجره را ببندید.

حال پروژه را اجرا کنید. مرورگر شما باید یک پیام خطای اعتبارسنجی به شما بدهد. دلیلش این است که اپلیکیشن شما از یک Valid Certificate استفاده نمی‌کند. هنگامی که پروژه را روی Windows Azure منتشر کنید دیگر این پیغام را نخواهید دید. چرا که سرور‌های مایکروسافت همگی لایسنس‌های معتبری دارند. برای اپلیکیشن ما می‌توانید روی Continue to this website را انتخاب کنید.

حال مرورگر پیش فرض شما باید صفحه Index از کنترلر home را به شما نمایش دهد.

اگر از یک نشست قبلی هنوز در سایت هستید (logged-in) روی لینک Log out کلیک کنید و از سایت خارج شوید.

روی لینک‌های About و Contact کلیک کنید. باید به صفحه ورود به سایت هدایت شوید چرا که کاربران ناشناس اجازه دسترسی به این صفحات را ندارند.

روی لینک Register کلیک کنید و یک کاربر محلی با نام Joe بسازید. حال مطمئن شوید که این کاربر به صفحات Home, About و Contact دسترسی دارد.

روی لینک CM Demo کلیک کنید و مطمئن شوید که داده‌ها را مشاهده می‌کنید.

حال روی یکی از لینک‌های ویرایش (Edit) کلیک کنید. این درخواست باید شما را به صفحه ورود به سایت هدایت کند، چرا که کاربران محلی جدید به نقش canEdit تعلق ندارند.

با کاربر user1 که قبلا ساختید وارد سایت شوید. حال به صفحه ویرایشی که قبلا درخواست کرده بودید هدایت می‌شوید.

اگر نتوانستید با این کاربر به سایت وارد شوید، کلمه عبور را از سورس کد کپی کنید و مجددا امتحان کنید. اگر همچنان نتوانستید به سایت وارد شوید، جدول AspNetUsers را بررسی کنید تا مطمئن شوید کاربر user1 ساخته شده است. این مراحل را در ادامه مقاله خواهید دید.

در آخر اطمینان حاصل کنید که می‌توانید داده‌ها را تغییر دهید.


اپلیکیشن را روی Windows Azure منتشر کنید

ابتدا پروژه را Build کنید. سپس روی نام پروژه کلیک راست کرده و گزینه Publish را انتخاب کنید.

در دیالوگ باز شده روی قسمت Settings کلیک کنید. روی File Publish Options کلیک کنید تا بتوانید Remote connection string را برای ApplicationDbContext و دیتابیس ContactDB انتخاب کنید.

اگر ویژوال استودیو را پس از ساخت Publish profile بسته و دوباره باز کرده اید، ممکن است رشته اتصال را در لیست موجود نبینید. در چنین صورتی، بجای ویرایش پروفایل انتشار، یک پروفایل جدید بسازید. درست مانند مراحلی که پیشتر دنبال کردید.

زیر قسمت ContactManagerContext گزینه Execute Code First Migrations را انتخاب کنید.

حال Publish را کلیک کنید تا اپلیکیشن شما منتشر شود. با کاربر user1 وارد سایت شوید و بررسی کنید که می‌توانید داده‌ها را ویرایش کنید یا خیر.

حال از سایت خارج شوید و توسط یک اکانت Google یا Facebook وارد سایت شوید، که در این صورت نقش canEdit نیز به شما تعلق می‌گیرد.


برای جلوگیری از دسترسی دیگران، وب سایت را متوقف کنید

در Server Explorer به قسمت Web Sites بروید. حال روی هر نمونه از وب سایت‌ها کلیک راست کنید و گزینه Stop Web Site را انتخاب کنید.

یک راه دیگر متوقف کردن وب سایت از طریق پرتال مدیریت Windows Azure است.


فراخوانی AddToRoleAsync را حذف و اپلیکیشن را منتشر و تست کنید

کنترلر Account را باز کنید و کد زیر را از متد ExternalLoginConfirmation حذف کنید.
await UserManager.AddToRoleAsync(user.Id, "CanEdit");
پروژه را ذخیره و Build کنید. حال روی نام پروژه کلیک راست کرده و Publish را انتخاب کنید.

دکمه Start Preview را فشار دهید. در این مرحله تنها فایل هایی که نیاز به بروز رسانی دارند آپلود خواهند شد.

وب سایت را راه اندازی کنید. ساده‌ترین راه از طریق پرتال مدیریت Windows Azure است. توجه داشته باشید که تا هنگامی که وب سایت شما متوقف شده، نمی‌توانید اپلیکیشن خود را منتشر کنید.

حال به ویژوال استودیو بازگردید و اپلیکیشن را منتشر کنید. اپلیکیشن Windows Azure شما باید در مرورگر پیش فرض تان باز شود. حال شما در حال مشاهده صفحه اصلی سایت بعنوان یک کاربر ناشناس هستید.

روی لینک About کلیک کنید، که شما را به صفحه ورود هدایت می‌کند.

روی لینک Register در صفحه ورود کلیک کنید و یک حساب کاربری محلی بسازید. از این حساب کاربری برای این استفاده می‌کنیم که ببینیم شما به صفحات فقط خواندنی (read-only) و نه صفحاتی که داده‌ها را تغییر می‌دهند دسترسی دارید یا خیر. بعدا در ادامه مقاله، دسترسی حساب‌های کاربری محلی (local) را حذف می‌کنیم.

مطمئن شوید که به صفحات About و Contact دسترسی دارید.

لینک CM Demo را کلیک کنید تا به کنترلر CmController هدایت شوید. 

روی یکی از لینک‌های Edit کلیک کنید. این کار شما را به صفحه ورود به سایت هدایت می‌کند. در زیر قسمت User another service to log in یکی از گزینه‌های Google یا Facebook را انتخاب کنید و توسط حساب کاربری ای که قبلا ساختید وارد شوید.

حال بررسی کنید که امکان ویرایش اطلاعات را دارید یا خیر.

نکته: شما نمی‌توانید در این اپلیکیشن از اکانت گوگل خود خارج شده، و با همان مرورگر با اکانت گوگل دیگری وارد اپلیکیشن شوید. اگر دارید از یک مرورگر استفاده می‌کنید، باید به سایت گوگل رفته و از آنجا خارج شوید. برای وارد شدن به اپلیکیشن توسط یک اکانت دیگر می‌توانید از یک مرورگر دیگر استفاده کنید.

دیتابیس SQL Azure را بررسی کنید

در Server Explorer دیتابیس ContactDB را پیدا کنید. روی آن کلیک راست کرده و Open in SQL Server Object Explorer را انتخاب کنید.

توجه: اگر نمی‌توانید گره SQL Databases را باز کنید و یا ContactDB را در ویژوال استودیو نمی‌بینید، باید مراحلی را طی کنید تا یک پورت یا یکسری پورت را به فایروال خود اضافه کنید. دقت داشته باشید که در صورت اضافه کردن Port Range‌ها ممکن است چند دقیقه زمان نیاز باشد تا بتوانید به دیتابیس دسترسی پیدا کنید.

روی جدول AspNetUsers کلیک راست کرده و View Data را انتخاب کنید.

حالا روی AspNetUserRoles کلیک راست کنید و View Data را انتخاب کنید.

اگر شناسه کاربران (User ID) را بررسی کنید، مشاهده می‌کنید که تنها دو کاربر user1 و اکانت گوگل شما به نقش canEdit تعلق دارند.

Cannot open server login error

اگر خطایی مبنی بر "Cannot open server" دریافت می‌کنید، مراحل زیر را دنبال کنید.

شما باید آدرس IP خود را به لیست آدرس‌های مجاز (Allowed IPs) اضافه کنید. در پرتال مدیریتی Windows Azure در قسمت چپ صفحه، گزینه SQL Databases را انتخاب کنید.

دیتابیس مورد نظر را انتخاب کنید. حالا روی لینک Set up Windows Azure firewall rules for this IP address کلیک کنید.

هنگامی که با پیغام "?The current IP address xxx.xxx.xxx.xxx is not included in existing firewall rules. Do you want to update the firewall rules" مواجه شدید Yes را کلیک کنید. افزودن یک آدرس IP بدین روش معمولا کافی نیست و در فایروال‌های سازمانی و بزرگ باید Range بیشتری را تعریف کنید.

مرحله بعد اضافه کردن محدوده آدرس‌های مجاز است.

مجددا در پرتال مدیریتی Windows Azure روی SQL Databases کلیک کنید. سروری که دیتابیس شما را میزبانی می‌کند انتخاب کنید.

در بالای صفحه لینک Configure را کلیک کنید. حالا نام rule جدید، آدرس شروع و پایان را وارد کنید.

در پایین صفحه Save را کلیک کنید.

در آخر می‌توانید توسط SSOX به دیتابیس خود متصل شوید. از منوی View گزینه SQL Server Object Explorer را انتخاب کنید. روی SQL Server کلیک راست کرده و Add SQL Server را انتخاب کنید.

در دیالوگ Connect to Server متد احراز هویت را به SQL Server Authentication تغییر دهید. این کار نام سرور و اطلاعات ورود پرتال Windows Azure را به شما می‌دهد.

در مرورگر خود به پرتال مدیریتی بروید و SQL Databases را انتخاب کنید. دیتابیس ContactDB را انتخاب کرده و روی View SQL Database connection strings کلیک کنید. در صفحه Connection Strings مقادیر Server و User ID را کپی کنید. حالا مقادیر را در دیالوگ مذکور در ویژوال استودیو بچسبانید. مقدار فیلد User ID در قسمت Login وارد می‌شود. در آخر هم کلمه عبوری که هنگام ساختن دیتابیس تنظیم کردید را وارد کنید.

حالا می‌توانید با مراحلی که پیشتر توضیح داده شد به دیتابیس Contact DB مراجعه کنید.

افزودن کاربران به نقش canEdit با ویرایش جداول دیتابیس

پیشتر در این مقاله، برای اضافه کردن کاربران به نقش canEdit از یک قطعه کد استفاده کردیم. یک راه دیگر تغییر جداول دیتابیس بصورت مستقیم است. مراحلی که در زیر آمده اند اضافه کردن کاربران به یک نقش را نشان می‌دهند.
در SQL Server Object Explorer روی جدول AspNetUserRoles کلیک راست کنید و View Data را انتخاب کنید.

حالا  RoleId را کپی کنید و در ردیف جدید بچسبانید.

شناسه کاربر مورد نظر را از جدول AspNetUsers پیدا کنید و مقدار آن را در ردیف جدید کپی کنید. همین! کاربر جدید شما به نقش canEdit اضافه شد.

نکاتی درباره ثبت نام محلی (Local Registration)

ثبت نام فعلی ما از بازنشانی کلمه‌های عبور (password reset) پشتیبانی نمی‌کند. همچنین اطمینان حاصل نمی‌شود که کاربران سایت انسان هستند (مثلا با استفاده از یک CAPTCHA). پس از آنکه کاربران توسط تامین کنندگان خارجی (مانند گوگل) احراز هویت شدند، می‌توانند در سایت ثبت نام کنند. اگر می‌خواهید ثبت نام محلی را برای اپلیکیشن خود غیرفعال کنید این مراحل را دنبال کنید:
  • در کنترلر Account متدهای Register را ویرایش کنید و خاصیت AllowAnonymous را از آنها حذف کنید (هر دو متد GET و POST). این کار ثبت نام کاربران ناشناس و بدافزارها (bots) را غیر ممکن می‌کند.
  • در پوشه Views/Shared فایل LoginPartial.cshtml_ را باز کنید و لینک Register را از آن حذف کنید.
  • در فایل  Views/Account/Login.cshtml نیز لینک Register را حذف کنید.
  • اپلیکیشن را دوباره منتشر کنید.


قدم‌های بعدی

برای اطلاعات بیشتر درباره نحوه استفاده از Facebook بعنوان یک تامین کننده احراز هویت، و اضافه کردن اطلاعات پروفایل به قسمت ثبت نام کاربران به لینک زیر مراجعه کنید.
برای یادگیری بیشتر درباره ASP.NET MVC 5 هم به سری مقالات Getting Started with ASP.NET MVC 5 می توانید مراجعه کنید. همچنین سری مقالات Getting Started with EF and MVC  مطالب خوبی درباره مفاهیم پیشرفته EF ارائه می‌کند.
بازخوردهای دوره
نصب و راه اندازی مقدماتی Full Text Search
از لوسین برای بانک‌های اطلاعاتی سبکی که قابلیت‌های Full text search ندارند، بهتر است استفاده شود. برای مثال اگر از SQLite استفاده می‌کنید یا حتی SQL Server CE (سبک‌ترین نسخه‌ی SQL Server که یک بانک اطلاعاتی embedded محسوب می‌شود)، لوسین بسیار مناسب است.
برای نمونه در سایت جاری از آن برای تهیه موتور جستجوی سایت استفاده شده و یا حتی برنامه‌ی سبک Viewer بانک اطلاعاتی سایت که با فرمت XML است، از لوسین استفاده می‌کند.
به صورت خلاصه برای کارهای سبک و یا بانک‌های اطلاعاتی embedded، استفاده از لوسین فوق العاده است.
اما برای کار با SQL Server کامل، واقعا نیازی به لوسین نیست. یک زیرساخت کامل و توکار برای Full Text Search دارد که با زبان T-SQL آن یکپارچه است. نگهداری و به روز رسانی آن توسط برنامه نویس در حد صفر است و یکبار که تعریف شد، به خوبی کار می‌کند. نگهداری ایندکس‌های لوسین خودکار نیست و باید توسط برنامه نویس به صورت مجزا هربار که اطلاعات تغییر می‌کند انجام شود.