مطالب
لیست تازه‌های IIS 7.5

IIS 7.5 که به همراه ویندوز سرور 2008 R2 ارائه می‌شود شامل تازه‌های زیر است:

  • بیش از 50 مورد cmdlet جدید مخصوص Powershell جهت مدیریت IIS
  • افزونه‌های جدید مدیریتی: Database Manager (مدیریت اس کیوال سرور از درون IIS و کنسول آن)، Configuration Editor (تولید خودکار اسکریپت‌های مدیریتی جهت اتوماسیون امور مرتبط)، IIS Reports و Request Filtering .
  • پشتیبانی از One-click publishing موجود در Visual Studio 10
  • Web Deployment Tool یا همان MS Deploy سابق جهت مدیریت بهتر برنامه‌های وب.
  • امکان ردیابی تغییرات در کانفیگ وب سرور
  • گزارشگیری بهتر از وضعیت کارآیی سرور
  • ساپورت دات نت جهت Server Core معرفی شده در ویندوز سرور 2008
  • WebDav که پیشتر به صورت یک افزونه‌ی آن معرفی شده بود، اکنون جزئی از IIS 7.5 است.
  • یکپارچگی با URLScan 3.0 جهت بالا بردن امنیت وب سرور.
  • FTP server services : با کنسول مدیریتی IIS یکپارچه شده است با بهبودهایی در نحوه‌ی تنظیم کردن و ردیابی آن.

جهت مطالعه بیشتر در مورد تازه‌های ویندوز سرور 2008 نگارش R2 می‌توان به مقالات زیر رجوع کرد:
Windows Server 2008 R2 new features - the complete list - Part 1: Virtualization
Windows Server 2008 R2 new features - the complete list - Part 2: Active Directory
Windows Server 2008 R2 new features - the complete list - Part 3: IIS 7.5 and Performance
Windows Server 2008 R2 new features - the complete list - Part 4: Administration

مطالب
Microsoft SQL Server 2008 Management Objects

یک سرویس کوچک ویندوز ان اتی نوشته‌ام که کارش این است که در پایان هر هفته، تمام دیتابیس‌های اس کیوال سرور موجود را یافته و اسکریپت تمام اشیاء آن‌ها را به صورت خودکار تولید می‌کند (از جداول گرفته تا تریگرها، رویه‌های ذخیره شده و غیره)، سپس کل مجموعه را فشرده کرده و سپس ایمیل می‌زند. این‌کار برای نگهداری تغییرات انجام شده در طول یک هفته لازم است.
برنامه با استفاده از امکانات SMO تهیه شده است و اگر علاقمند بودید که این‌کار را انجام دهید، می‌توانید به مقاله‌های زیر رجوع کنید:

Making a database clone using SMO

Using the SqlServer.Management.Smo

SQL Server: SMO Scripting Basics


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

Could not load file or assembly 'Microsoft.SqlServer.Management.Sdk.Sfc, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot find the file specified.


خوشبختانه مایکروسافت این کتابخانه‌ها را به صورت مجزا هم برای دریافت قرار داده است و می‌توان آن‌ها را نصب نمود تا برنامه بدون اشکال اجرا شود. به صفحه زیر و قسمت Microsoft SQL Server 2008 Management Objects مراجعه نمائید:
اینجا کلیک نمائید

البته همانطور که در صفحه ذکر شده نیز عنوان گردیده است، به MSXML 6.0 هم نیاز می‌باشد که لینک دریافت آن در ابتدای صفحه فوق موجود است.

مطالب
قسمت اول - ساخت گزارش در محیط Telerik Reporting
یکی از ضروریات نرم افزارها وجود گزارشات مختلف در قالب لیست‌ها ، نمودارها و ... در آنها می‌باشد.یک نرم افزار خوب باید توانایی ارائه گزارشات خوب و زیبا را نیز داشته باشد.گزارشات در حقیقت نمایشی از داده‌ها هستند که عموما به چاپ می‌رسند. مورد دیگری که در خصوص گزارشات حائز اهمیت می‌باشد ، تبدیل آنها به فرمت‌های مختلف جهت حمل و جابه جایی آسان از سیستمی به سیستم دیگر می‌باشد. برای مثال تبدیل گزارشات به قالب Pdf مزایایی بسیاری از نظر قابل حمل بودن در پی خواهد داشت. در برنامه نویسی دات نت گزارشات را می‌توان توسط دستورات چاپ در دات تهیه ، نمایش و چاپ نمود. اما تهیه گزارش توسط دستورات دات نت کاری مشکل و طاقت فرسا می‌باشد. همچنین امکان تبدیل این گزارشات به فرمت‌های دیگر نظیر Pdf ، به راحتی انجام نمی‌شود و باید از کلاس‌ها و ابزارهای جانبی که برای این کار تهیه شده اند استفاده نمود . از این رو ابزارهای مختلفی در جهت تهیه گزارشات به وجود آمدند.ابزارهایی نظیر :

• Crystal Report
• Stimul Report
• Telerik Reporting
• … 

در ادامه این سری آموزش‌ها قصد داریم Telerik Reporting و نحوه تهیه گزارش با آن را مورد بررسی قرار دهیم. این ابزار امکانات بسیاری در خصوص تهیه گزارش برنامه‌های دات نتی نظیر Windows Form ، Asp.net و ... در اختیار ما قرار می‌دهد.در ادامه و برای شروع ، ساخت یک گزارش ساده در این محیط را بررسی میکنیم.

 
 نکته : گزارشاتی که توسط Telerik Reporting تهیه می‌شوند به وسیله کدهای C# جنریت می‌شوند.بنابراین همیشه توصیه می‌شود گزارشات خود را درون یک یا چند پروژه Class Library قرار دهیم و از این پس ، این گزارشات از درون پروژه‌های دیگر (ویندوزی ، وب و ...) در دسترس هستند.کافی ست پروژه Class Library را به عنوان Reference به پروژه مورد نظر خود اضافه کنیم..  برای شروع می‌توان یک پروژه جدید  از نوع Class Library  ایجاد کرد.پس از آن روی نام پروژه راست کلیک کنید و گزینه Telerik Report را انتخاب نمایید.پس از تعیین نام گزارش کلید Ok را کلیک نمایید.

انتخاب گزینه Telerik Reporting از پنجره New Item


در این حالت فایل گزارش به پروژه افزوده می‌شود. در ادامه می‌توانید توسط ویزاردی که نمایش داده می‌شود کارهای عمومی مربوط به پیاده سازی گزارش (انتخاب منبع داده(Data Source) ، ساخت Query جهت بارگذاری اطلاعات ، فیلدهایی که باید نمایش داده شوند ، گروه بندی داده‌ها و ...) را توسط این ویزارد انجام دهید. برای اینکار در پنجره ای که نمایش داده می‌شود بر روی کلید Next کلیک نمایید.
جهت ایجاد یک گزارش جدید در پنجره  Report Choose Page گزینه New Report را انتخاب نموده و کلید Next را کلیک نمایید.
جهت انتخاب منبع داده گزارش در پنجره Choose Data Source گزینه Add New Data Source را انتخاب نمایید.در این حالت می‌توانید گزینه‌های متفاوتی را به عنوان منبع داده گزارش خود انتخاب نمایید. گزینه‌های نمایش داده شده به شرح ذیل است:
• Sql Data Source : جهت اتصال مستقیم به بانک اطلاعات Microsoft Sql Server
• Object Data Source :  جهت اتصال به کلاس‌های لایه Business و بارگذاری داده از این کلاس ها
• Entity Data Source : جهت اتصال به  Entity Framework
• Open Access Data Source : جهت اتصال به Open Access ORM ساخت شرکت Telerik
• Cube Data Source : جهت اتصال و نمایش داده‌های تحلیل شده
  در ادامه برای اینکه بتوان مستقیما به Sql Server وصل شد و Query‌های مربوط به گزارش را روی آن اجرا نمود؛ می‌توان گزینه Sql Data Source را انتخاب نمود و بر روی کلید Ok کلیک کرد.سپس در پنجره Choose Your Data Connection گزینه New Connection را کلیک کنید و یک اتصال به بانک مورد نظر خود ایجاد کنید.پس ایجاد و تست Connection ساخته شده روی Next  کلیک کنید.در پنجره Save the connection string می‌توان نامی را جهت Connection string انتخاب کرد تا Connection string با همان نام در فایل Config پروژه ذخیره شود.در ادامه کلید Next را کلیک کرده و وارد مرحله بعد شوید. در پنجره Configure Data Source Command گزینه Query Builder را جهت ساخت Query مورد نظر برای بارگذاری داده‌ها انتخاب نمایید.

انتخاب جداول جهت ساخت Query


پنجره ساخت Query

پس از ساخت Query مورد نظر کلید Ok را کلیک نمایید. در پنجره Configure Data Source Command کوئری ساخته شده به شما نمایش داده می‌شود.کلید Next را کلیک کنید. 

سپس وارد مرحله Preview Data Source Result می‌شوید که در آن قادر خواهید بود پیش نمایشی از داده هایی که بعدا توسط Query ساخته شده بارگذاری خواهند شد را مشاهده نمایید. Next را کلیک نموده تا وارد مرحله بعد شوید.مرحله بعد Standard Report Type می‌باشد که در این مرحله شما می‌توانید نوع گزارش خود را انتخاب نمایید و کلید Next را فشار دهید.در بخش Design Data Layout چند فیلد را از بخش سمت چپ (Available Fields) انتخاب نموده و کلید Details را کلیک نمایید.فیلدهای انتخاب شده به بخش Details گزارش اضافه خواهند شد.در ادامه Next را کلیک کنید تا وارد بخش Choose Report Layout شوید.شما می‌توانید در این بخش یک حالت نمایشی را برای گزارش خود انتخاب نمایید و Next را کلیک نمایید.در بخش Choose Report Style یک قالب بندی جهت گزارش خود انتخاب نمایید.در ادامه Next و سپس Finish را کلیک نمایید.کدهای گزارش Generate شده می‌توان در قسمت Designer گزارش را مشاهده نمود. 

در این حالت کارهای زیر توسط Wizard به صورت اتوماتیک انجام خواهد شد:
• بایند شدن اتوماتیک فیلدهای گزارش به ستوان‌های مرتبط
• اعمال قالب بندی انتخاب شده برای صفحه و سر ستونها
• افزودن تاریخ و شماره صفحه به پایین گزارش
در ادامه پروژه را Rebuild کرده و گزینه Preview را در Designer جهت نمایش ، پیش نمایش گزارش کلیک نمایید.

نکته : در هر برنامه‌ی گزارش سازی بخش Designer گزارش به 4 بخش کلی تقسیم می‌شود:
•  Report Header: مواردی که در این بخش از گزارش قرار میگیرند در بالای صفحه اول گزارش نمایش داده می‌شوند.
•  Page Header: مواردی که در این بخش از گزارش قرار میگیرند در بالای همه صفحات گزارش قرار گرفته و تکرار می‌شوند.
•  Details: داده‌های اصلی گزارش که شامل جزئیات و بخش اصلی گزارش می‌باشند و سطر به سطر نیز تکرار می‌شوند در این بخش قرار می‌گیرند.
•  Page Footer: مواردی که در این بخش از گزارش قرار میگیرند در پایین همه صفحات نمایش داده می‌شوند.
•  Report Footer:مواردی که در این بخش قرار می‌گیرند در پایین صفحه آخر گزارش نمایش داده می‌شوند.  

ادامه دارد ...
مطالب
Optimize for unknown

مفهومی در SQL Server وجود دارد به نام parameter sniffing که شرح آن به صورت زیر است.
ابتدا رویه ذخیره شده زیر را در نظر بگیرید:

create procedure test (@pid int)
as
select * from Sales.SalesOrderDetail
where ProductID = @pid
استفاده از کوئری‌های پارامتری یکی از بهترین تمرین‌های کاری با SQL server است؛ از آنجائیکه در این حالت plan تهیه شده مجددا مورد استفاده قرار گرفته، همچنین از SQL injection نیز جلوگیری خواهد کرد، زیرا برای نمونه در مثال فوق تنها pid از نوع int پذیرفته می‌شود و نه هر ورودی خطرناک دیگری.
اما این نوع کوئری‌ها یک مشکل را نیز به همراه خود دارند. این plan تهیه شده به ازای اولین ورودی رویه ذخیره شده تهیه می‌شود (parameter sniffing) و الزامی ندارد که برای دومین ورودی و فراخوانی‌های بعدی، بهترین plan باشد.

برای حل این مشکل راه‌های زیادی هست:
الف) انتساب پارامترهای یک رویه ذخیره شده به متغیری محلی

create procedure test (@pid int)
as
Declare @mpid int
Set @mpid = @pid
select * from Sales.SalesOrderDetail
where ProductID = @mpid
در اینجا پارامتر ورودی مستقیما در کوئری استفاده نشده است و SQL Server این متغیر محلی را sniff نخواهد کرد.

ب) استفاده از گزینه RECOMPILE که سبب خواهد شد به ازای هر ورودی یک plan بهینه تهیه شود. این مورد مصرف CPU بالایی را به همراه خواهد داشت.

ج) راه حل ارائه شده در SQL Server 2005
استفاده از روش الف به علاوه اضافه کردن گزینه کمکی زیر به انتهای اسکریپت فوق

OPTION (OPTIMIZE FOR(@pid = 544))

در اینجا فرض بر این است که می‌دانیم pid=544 بسیار مورد استفاده قرار خواهد گرفت، بنابراین این معرفی را به موتور بهینه ساز SQL Server ارائه خواهیم کرد.

د) راه حل ارائه شده در SQL Server 2008
با استفاده از Optimize for unknown که در اس کیوال سرور 2008 معرفی شده است، مزیت استفاده از کوئری‌های پارامتری همانند استفاده مجدد از plan تهیه شده، حفظ گشته اما این plan‌ تهیه شده اولیه بر اساس اولین مقدار پاس شده، تهیه نگردیده و حالت عمومی‌تر و بهینه‌تری را برای اکثر مقادیر پاس شده خواهد داشت.

create procedure test (@pid int)
as
select * from Sales.SalesOrderDetail
where ProductID = @pid

OPTION(OPTIMIZE FOR (@pid UNKNOWN))

جهت مطالعه بیشتر (+ و + و +)

مطالب
JQuery 1.3 ارائه شد

روز قبل، نگارش رسمی و نهایی jQuery 1.3 ارائه شد و بلافاصله هم فایل مخصوص آن جهت بکارگیری intellisense ویژوال استودیو، توسط علاقمندان تهیه و عرضه گردید.

تازه‌های این نگارش:
  • Sizzle : یک موتور CSS selector قدرتمند (400 درصد بهبود سرعت نسبت به عملکرد کتابخانه قبلی در این مورد)
  • بازنگری در نحوه مدیریت رخدادها
  • موتور تزریق HTML‌ بسیار سریع (تا 15 برابر سریعتر نسبت به کتابخانه قبلی)
  • موتور بسیار سریع موقعیت یابی
  • تشخیص نوع مرورگر در آن متوقف شده و بجای آن از تشخیص ویژگی‌ها برای ماندگاری بیشتر این کتابخانه در سال‌های آتی استفاده گردیده است. (بجای بررسی userAgent ، از باگ‌های شناخته شده یا ویژگی‌های خاص، جهت تشخیص مرورگر استفاده می‌شود تا بازه وسیعی از محصولات مشابه را بتوانند پوشش دهند)
لیست کامل این تغییرات را در این آدرس می‌توانید ملاحظه نمائید.
  • جهت مشاهده و آزمایش بهبود کارآیی این کتابخانه لطفا به این صفحه مراجعه کنید. (لیست کامل این آزمایشات در انتهای صفحه لیست تغییرات، قابل دسترسی است)
همچنین تیم مربوطه در پی آن است تا در طی یکی دو هفته آینده، نگارش jQuery 1.3.1 را نیز بر اساس بازخوردهای جدید جامعه برنامه نویس‌ها ارائه دهد.

مانند همیشه این کتابخانه در دو نگارش فشرده شده (جهت استفاده در سایت‌ها) و نگارش عادی و حجیم‌تر (جهت برنامه نویسی و دیباگ کردن کدها) ارائه شده است. چون کدها در Google code هاست شده احتمالا دسترسی به آن مشکل خواهد بود. این مجموعه را از این آدرس می‌توانید دریافت کنید.

توصیه می‌شود از سرورهای سریع گوگل بعنوان هاست کتابخانه جی‌کوئری سایت‌های خود استفاده کنید. برای این منظور از آدرس زیر می‌توان استفاده کرد:
http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js


اشتراک‌ها
یک روش ساده برای دور زدن تحریم ها !

با توجه به اینکه یکسری از سایت‌ها مثل docker و بعضی از repo‌های لینوکسی و .... ایران رو تحریم کردند و نمیشه از سرویس هاشون استفاده کرد اتفاقی با این سایت برخورد کردم که راه حل جالب و ساده ای برای رفع این مشکل در ایران ارائه داده.

شرکت بنیان سرویس ارائه داده است که تحریم‌شکن می‌باشد. بر این اساس شما DNS Server خود را به IP این شرکت تغییر می‌دهید بعد از آن درخواست‌های شما برای سرویس‌های تحریم شده پاسخ داده می‌شود.

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

یک روش ساده برای دور زدن تحریم ها !
مطالب
ابزارهای مهاجرت به OLTP درون حافظه‌ای در SQL Server 2014
در SQL Server 2014، به Management studio آن ابزارهای جدیدی اضافه شده‌اند تا کار تبدیل و مهاجرت جداول معمولی، به جداول بهینه سازی شده‌ی برای حافظه را ساده‌تر کنند. برای مثال امکان جدیدی به نام Transaction performance collector جهت بررسی کارآیی تراکنش‌های جداول و یا رویه‌های ذخیره شده در محیط کاری جاری، طراحی شده‌است. پس از آن، این اطلاعات را آنالیز کرده و بر اساس میزان استفاده از آن‌ها، توصیه‌هایی را در مورد مهاجرت یا عدم نیاز به مهاجرت به سیستم جدید OLTP درون حافظه‌ای ارائه می‌دهد. در ادامه این ابزارهای جدید را بررسی خواهیم کرد.


ابزار Memory Optimization Advisor

Memory Optimization Advisor یک Wizard مانند است که از آن برای گرفتن مشاوره در مورد تبدیل جداول موجود مبتنی بر دیسک سخت، به نمونه‌های بهینه سازی شده برای حافظه می‌توان استفاده کرد. کار آن بررسی ساختار جداولی است که قصد مهاجرت آن‌ها را دارید. برای مثال همانطور که پیشتر نیز عنوان شد، جداول بهینه سازی شده برای حافظه محدودیت‌هایی دارند؛ مثلا نباید کلید خارجی داشته باشند. این Wizard یک چنین مواردی را آنالیز کرده و گزارشی را ارائه می‌دهد. پس از اینکه مراحل آن‌را به پایان رساندید و مشکلاتی را که گزارش می‌دهد، برطرف نمودید، کد تبدیل جدول را نیز به صورت خودکار تولید می‌کند.
برای دسترسی به آن، فقط کافی است بر روی نام جدول خود کلیک راست کرده و گزینه‌ی memory optimization advisor را انتخاب کنید.


در دو قسمت اول این Wizard، کار بررسی ساختار جدول در حال مهاجرت صورت می‌گیرد. اگر نوع داده‌ای در آن پشتیبانی نشود یا قیود ویژه‌ای در آن تعریف شده باشند، گزارشی را جهت رفع، دریافت خواهید کرد. پس از رفع آن، به صفحه‌ی گزینه‌های مهاجرت می‌رسیم:


همانطور که ملاحظه می‌کنید، گروه فایل ایجاد شده در قسمت قبل، به صورت خودکار انتخاب شده‌است.
در ادامه می‌توان نام دیگری را برای جدول مبتنی بر دیسک وارد کرد. در اینجا به صورت خودکار کلمه‌ی old به آخر نام جدول اضافه شده‌است. در حین تولید جدول جدید بهینه سازی شده‌ی بر اساس ساختار جدول فعلی، این جدول قدیمی به صورت خودکار تغییر نام خواهد یافت و کلیه اطلاعات آن حفظ می‌شود.
همچنین تخمینی را نیز از مقدار حافظه‌ی مورد نیاز برای نگهداری این جدول جدید درون حافظه‌ای نیز ارائه می‌دهد. در این مثال چون رکوردی در جدول انتخابی وجود نداشته‌است، تخمین آن صفر است. عدد ارائه شده توسط آن بسیار مهم است و باید به همین میزان برای سیستم خود حافظه تهیه نمائید و یا از حافظه‌ی موجود استفاده کنید.
در پایین صفحه می‌توان انتخاب کرد که آیا داده‌های جدول فعلی، به جدول درون حافظه‌ای انتقال یابند یا خیر. به علاوه نوع ماندگاری اطلاعات آن نیز قابل تنظیم است. اگر گزینه‌ی آخر را انتخاب کنید به معنای حالت SCHEMA_ONLY است. حالت پیش فرض آن SCHEMA_AND_DATA می‌باشد که در قسمت‌های قبل بیشتر در مورد آن بحث شد.

در دو صفحه‌ی بعد، کار انتخاب hash index و range index انجام می‌شود:


در اینجا hash index بر روی فیلد ID تولید شده‌است، به همراه تعیین bucket count آن و در صفحه‌ی بعدی range index بر روی فیلد تاریخ تعریف گردیده‌است:


در آخر می‌توان با کلیک بر روی دکمه‌ی Script، صرفا دستورات T-SQL تغییر ساختار جدول را دریافت کرد و یا با کلیک بر روی دکمه‌ی migrate به صورت خودکار کلیه موارد تنظیم شده را اجرا نمود.


خلاصه‌ی این مراحل که توسط دکمه‌ی Script آن تولید می‌شود، به صورت زیر است:
USE [testdb2]
GO

EXEC dbo.sp_rename @objname = N'[dbo].[tblNormal]', @newname = N'tblNormal_old', @objtype = N'OBJECT'
GO

USE [testdb2]
GO

SET ANSI_NULLS ON
GO

CREATE TABLE [dbo].[tblNormal]
(
[CustomerID] [int] NOT NULL,
[Name] [nvarchar](250) COLLATE Persian_100_CI_AI NOT NULL,
[CustomerSince] [datetime] NOT NULL,

INDEX [ICustomerSince] NONCLUSTERED 
(
[CustomerSince] ASC
),
CONSTRAINT [tblNormal_primaryKey] PRIMARY KEY NONCLUSTERED HASH 
(
[CustomerID]
)WITH ( BUCKET_COUNT = 131072)
)WITH ( MEMORY_OPTIMIZED = ON , DURABILITY = SCHEMA_AND_DATA )

GO

INSERT INTO [testdb2].[dbo].[tblNormal] ([CustomerID], [Name], [CustomerSince]) SELECT [CustomerID], [Name], [CustomerSince] FROM [testdb2].[dbo].[tblNormal_old] 

GO
که در آن ابتدا کار تغییر نام جدول قبلی صورت می‌گیرد. سپس یک جدول جدید با ویژگی MEMORY_OPTIMIZED = ON را ایجاد می‌کند. در ساختار این جدول، hash index و range index تعریف شده، قابل مشاهده هستند. در آخر نیز کلیه اطلاعات جدول قدیمی را به جدول جدید منتقل می‌کند.

علاوه بر memory optimization advisor مخصوص جداول، ابزار دیگری نیز به نام Native compilation advisor برای آنالیز رویه‌های ذخیره شده تهیه شده‌است:



آیا سیستم فعلی ما واقعا نیازی به ارتقاء به جداول درون حافظه‌ای دارد؟

تا اینجا در مورد نحوه‌ی ایجاد جداول درون حافظه‌ای و یا نحوه‌ی تبدیل جداول موجود را به ساختار جدید بررسی کردیم. ولی آیا واقعا یک چنین تغییراتی برای ما سودمند هستند؟ برای پاسخ دادن به این سؤال ابزاری به نام AMR به management studio 2014 اضافه شده‌است (Analyze, Migrate, Report). کار آن تحت نظر قرار دادن جداول و رویه‌های ذخیره شده‌ی بانک اطلاعاتی است و سپس بر اساس بار سیستم، تعداد درخواست‌های همزمان و میزان استفاده از جداول و تراکنش‌های مرتبط با آن‌ها، گزارشی را ارائه می‌دهد. بر این اساس بهتر می‌توان تصمیم گرفت که کدام جداول بهتر است به جداول درون حافظه‌ای تبدیل شوند.
برای تنظیم آن باید مراحل ذیل طی شوند:
در Management Studio، به برگه‌ی Object Explorer آن مراجعه کنید. سپس پوشه‌ی Management آن‌را یافته و بر روی گزینه‌ی Data Collection کلیک راست نمائید:


در اینجا گزینه‌ی Configure Management Data Warehouse را انتخاب نمائید. در صفحه‌ی باز شده، ابتدا بانک اطلاعاتی مدنظر را انتخاب نمائید. همچنین بهتر است بر روی دکمه‌ی new کلیک کرده و یک بانک اطلاعاتی جدید را برای آن ایجاد نمائید، تا دچار تداخل اطلاعاتی و ساختاری نگردد:


در ادامه نام کاربری را که قرار است کار مدیریت ثبت و جمع آوری اطلاعات را انجام دهد، به همراه نقش‌های آن انتخاب نمائید:


و در آخر در صفحه‌ی بعدی بر روی دکمه‌ی Finish کلیک کنید.

پس از ایجاد و انتخاب بانک اطلاعاتی Management Data Warehouse، نوبت به تنظیم گزینه‌های جمع آوری اطلاعات است:


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


در صفحه‌ی بعد، گزینه‌ی «Transaction Performance Collection Sets» را انتخاب نمائید که دقیقا گزینه‌ی مدنظر ما جهت یافتن آماری از وضعیت تراکنش‌های سیستم است.
در ادامه بر روی گزینه‌های next و finish کلیک کنید تا کار تنظیمات به پایان برسد.

اکنون اگر به لیست وظایف تعریف شده در SQL Server agent مراجعه کنید، می‌توانید، وظایف مرتبط با جمع آوری داده‌ها را نیز مشاهده نمائید:


وظایف Stored Procedure Usage Analysis هر نیم ساعت یکبار و وظایف Table Usage Analysis هر 15 دقیقه یکبار اجرا می‌شوند. البته امکان اجرای دستی این وظایف نیز مانند سایر وظایف SQL Server وجود دارند.

همچنین در پوشه‌ی management، گزینه‌ی Data collection نیز دو زیر شاخه اضافه شده‌اند که نمایانگر آنالیز میزان مصرف جداول و رویه‌های ذخیره شده می‌باشند:


پس از این کارها باید مدتی صبر کنید (مثلا یک ساعت) تا سیستم به صورت معمول کارهای متداول خودش را انجام دهد. پس از آن می‌توان به گزارشات AMR مراجعه کرد.


برای اینکار بر روی بانک اطلاعاتی Management Data Warehouse که در ابتدای عملیات ایجاد شد، کلیک راست نمائید و سپس مراحل ذیل را طی کنید:
Reports > Management Data Warehouse > Transaction Performance Analysis Overview


در گزارش ایجاد شده، ذیل گزینه‌ی usage analysis لینک‌هایی وجود دارند که با مراجعه به آن‌ها، چارت‌هایی از میزان مصرف بانک‌های اطلاعاتی مختلف سیستم ارائه می‌شود. اگر پیام No data available را مشاهده کردید، یعنی هنوز باید مقداری صبر کنید تا کار جمع آوری اطلاعات به پایان برسد.
در این چارت‌ها بانک‌های اطلاعاتی که در سمت راست، بالای تصویر قرار می‌گیرند، انتخاب مناسبی برای تبدیل به بانک‌های اطلاعاتی درون حافظه‌ای هستند. محور افقی آن از چپ به راست بیانگر میزان کاهش سختی انتقال یک جدول به جدول درون حافظه‌ای است (با درنظر گرفتن تمام مسایلی که باید تغییر کنند یا نوع‌های داده‌ای که باید اصلاح شوند) و محور عمودی آن نمایانگر میزان بالا رفتن پاسخ دهی سیستم در جهت انجام کار بیشتر است.


هر زمان هم که کار تصمیم‌گیری شما به پایان رسید، می‌توانید بر روی گزینه‌ی Data collection کلیک راست کرده و آن‌را غیرفعال نمائید.

 
برای مطالعه بیشتر

SQL Server 2014 Field Benchmarking In-Memory OLTP and Buffer Pool Extension Features 
New AMR Tool: Simplifying the Migration to In-Memory OLTP
A Tour of the Hekaton AMR Tool
SQL Server 2014 Memory Optimization Advisor
Getting started with the AMR tool for migration to SQL Server In-memory OLTP Tables
How to Use Microsoft's AMR Tool
SQL Server 2014's Analysis, Migrate, and Report Tool
مطالب
مدیریت حالت در برنامه‌های Blazor توسط الگوی Observer - قسمت اول
نیاز به مدیریت حالت در برنامه‌های Blazor

«حالت» یا state، شیءای است، حاوی اطلاعاتی که برنامه با آن سر و کار دارد. بنابراین مدیریت حالت، روشی است برای ردیابی و مدیریت داده‌های مورد استفاده‌ی در برنامه و تقریبا تمام برنامه‌ها، به نحوی به آن نیاز دارند. هر کامپوننت در Blazor، دارای state خاص خودش است و این state از سایر کامپوننت‌ها کاملا مستقل و ایزوله‌است. این مورد با بزرگ‌تر شدن برنامه و برقراری ارتباط بین کامپوننت‌ها، مشکل ایجاد می‌کند. برای مثال اگر قرار است در منوی بالای سایت، تعداد محصولات موجود در سبد خرید یک شخص را نمایش دهیم، این تعداد، حاصل تعامل او با چندین کامپوننت مجزا خواهد بود که این‌ها الزاما در یک سلسه مراتب هم قرار نمی‌گیرند و به سادگی نمی‌توان اطلاعات را به صورت آبشاری در بین آن‌ها به اشتراک گذاشت. به همین جهت نیاز به روشی برای مدیریت حالت و به اشتراک گذاری آن در بین کامپوننت‌های مختلف برنامه وجود دارد و خوشبختانه چون Blazor به همراه یک سیستم تزریق وابستگی‌های توکار است، پیاده سازی یک چنین مدیریت کننده‌ای، ساده‌است.


استفاده از الگوی Observer جهت مدیریت حالت برنامه‌های Blazor


زمانیکه همانند تصویر فوق با یک کامپوننت کار می‌کنیم، کاربر همواره کارش از تعامل با یک View آغاز می‌شود. این تعامل سبب صدور رخ‌دادهایی می‌شود که این رخ‌دادها، حالت و state کامپوننت را تغییر می‌دهند. تغییر حالت کامپوننت نیز بلافاصله سبب به‌روز رسانی View می‌شود. در این مثال، حالت کامپوننت، داخل همان کامپوننت نگه‌داری می‌شود؛ مانند فیلدهایی که در قسمت code@ یک کامپوننت Blazor تعریف می‌کنیم و محدود به همان کامپوننت هستند.
با بزرگتر شدن برنامه، زمانی خواهد رسید که نیاز است حالت یک کامپوننت را با کامپوننت‌های دیگر به اشتراک گذاشت. در این حالت باید این state را از داخل کامپوننت مدنظر استخراج کرد و در جائی دیگر قرار داد که عموما به آن state store گفته می‌شود:


در تصویر فوق، در بالای آن یک state store را داریم که محل نگه‌داری و ذخیره سازی حالت اشتراکی بین کامپوننت‌ها است. سپس برای نمونه دو کامپوننت دیگر را داریم که رابطه‌ی بین آن‌ها، همان رابطه‌ی مثلثی است که در تصویر اول این مطلب مشاهده کردیم. برای مثال در اثر تعامل کاربری با View کامپوننت 1، رخ‌دادی صادر خواهد شد. مدیریت این رخ‌داد، سبب تغییر state خواهد شد، اما اینبار این state دیگر داخل کامپوننت 1 قرار ندارد؛ بلکه داخل state store است و این store پس از آگاه شدن از تغییر وضعیت خود، دو کامپوننتی را که از آن تغدیه می‌کنند، جهت به روز رسانی Viewهایشان، مطلع می‌کند. همین چرخه در مورد کامپوننت 2 نیز برقرار است. اگر تعاملی با آن صورت گیرد، در نهایت اثر آن به هر دو کامپوننت متصل به state store اشتراکی، اطلاع رسانی می‌شود تا Viewهای هر دوی آن‌ها به روز رسانی شوند. الگویی را که در اینجا مشاهده می‌کنید، در اصل یک الگوی Observer است:


در الگوی مشاهده‌گر، یک Subject را داریم که تعداد زیادی Observer، مشترک آن هستند. در این مثال ما، Subject، همان State Store است و Observerها دقیقا همان کامپوننت‌های مشترک به آن. Observerها به تغییرات Subject گوش فرا داده و بلافاصله بر اساس آن واکنش مناسبی را نشان می‌دهند.


پیاده سازی الگوی Observer جهت مدیریت حالت برنامه‌های Blazor

زمانیکه یک برنامه‌ی متداول Blazor را توسط قالب پیش‌فرض آن ایجاد می‌کنیم، به همراه یک کامپوننت Counter است:
@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}
در این مثال فیلد currentCount، همان حالت کامپوننت جاری است که تنها مختص به آن است. اکنون می‌خواهیم این حالت را با کامپوننتی که منوی سمت چپ صفحه را تشکیل می‌دهد (یعنی Client\Shared\NavMenu.razor) به اشتراک گذاشته و با کلیک بر روی دکمه‌ی این شمارشگر، عدد حاصل را علاوه بر View این کامپوننت، در کنار برچسب منوی آن نیز نمایش دهیم.
بنابراین در قدم اول نیاز به یک State Store اشتراکی را داریم که بتوانیم توسط آن، مقدار جاری currentCount را ذخیره کرده و سپس تغییرات آن‌را جهت به روز رسانی دو View (در کامپوننت‌های Counter و NavMenu)، به مشترکین آن اطلاع رسانی کنیم. به همین جهت ابتدا پوشه‌ی جدید Stores را در ریشه‌ی پروژه‌ی Blazor ایجاد می‌کنیم. نام این پوشه، از این جهت یک اسم جمع است که یک برنامه بنابر نیاز خودش می‌تواند چندین State Store را داشته باشد. سپس داخل این پوشه، پوشه‌ی دیگری را به نام CounterStore، ایجاد می‌کنیم.
در اینجا در ابتدا شیء حالت مدنظر را ایجاد می‌کنیم که برای نمونه بر اساس نیاز برنامه و این مثال، از مقدار نهایی کلیک بر روی دکمه‌ی شمارشگر تشکیل می‌شود:
namespace BlazorStateManagement.Stores.CounterStore
{
    public class CounterState
    {
        public int Count { get; set; }
    }
}
از این حالت، در مخزن حالت جدید زیر استفاده خواهیم کرد:
using System;

namespace BlazorStateManagement.Stores.CounterStore
{
    public interface ICounterStore
    {
        void DecrementCount();
        void IncrementCount();
        CounterState GetState();

        void AddStateChangeListener(Action listener);
        void BroadcastStateChange();
        void RemoveStateChangeListener(Action listener);
    }
}

using System;
namespace BlazorStateManagement.Stores.CounterStore
{
    public class CounterStore : ICounterStore
    {
        private readonly CounterState _state = new();
        private Action _listeners;

        public CounterState GetState()
        {
            return _state;
        }

        public void IncrementCount()
        {
            _state.Count++;
            BroadcastStateChange();
        }

        public void DecrementCount()
        {
            _state.Count--;
            BroadcastStateChange();
        }

        public void AddStateChangeListener(Action listener)
        {
            _listeners += listener;
        }

        public void RemoveStateChangeListener(Action listener)
        {
            _listeners -= listener;
        }

        public void BroadcastStateChange()
        {
            _listeners.Invoke();
        }
    }
}
توضیحات:
- مخزن حالت پیاده سازی شده‌ی بر اساس الگوی مشاهده‌گر، نیاز دارد تا بتواند لیست مشاهده‌گرها را ثبت کند. به همین جهت به همراه متدهای AddStateChangeListener جهت ثبت یک مشاهده‌گر جدید و RemoveStateChangeListener، جهت حذف مشاهده‌گری از لیست موجود است.
- همچنین الگوی مشاهده‌گر باید بتواند تغییرات صورت گرفته‌ی در حالتی را که نگه‌داری می‌کند (CounterState در اینجا)، به مشترکین خود اطلاع رسانی کند. اینکار را توسط متد BroadcastStateChange انجام می‌دهد. هر زمانیکه این متد فراخوانی شود، Actionهایی که به صورت پارامتر به متد AddStateChangeListener ارسال شده‌اند، به صورت خودکار اجرا خواهند شد. این کار سبب می‌شود تا بتوان منطق خاصی را مانند به روز رسانی UI، در سمت کامپوننت‌های مشترک به این مخزن، پیاده سازی کرد.
- در اینجا همچنین متدهایی برای افزایش و کاهش مقدار Count را نیز به همراه اطلاع رسانی به مشترکین، مشاهده می‌کنید.

پس از این تعریف نیاز است سرویس Store ایجاد شده را به برنامه معرفی کرد:
namespace BlazorStateManagement.Client
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            //...
            builder.Services.AddScoped<ICounterStore, CounterStore>();
            //...
        }
    }
}
با توجه به اینکه در هر دو حالت Blazor Server و همچنین Blazor Wasm، طول عمر Scoped، دقیقا مانند حالت Singleton عمل می‌کند، سرویس ICounterStore و حالت نگهداری شده‌ی توسط آن، تا پایان عمر برنامه (بسته شدن مرورگر یا ریفرش کامل صفحه‌ی جاری)، در حافظه باقی مانده و وهله سازی مجدد نخواهد شد. به همین جهت تزریق آن در کامپوننت‌های مختلف برنامه، دقیقا حالت مخزن داده‌ی اشتراکی را پیدا خواهد کرد. این مورد یکی از مزیت‌های کار با Blazor است که به همراه یک سیستم تزریق وابستگی‌های توکار است.


تغییر کامپوننت‌های برنامه برای استفاده از سرویس ICounterStore

پس از معرفی سرویس ICounterStore به سیستم تزریق وابستگی‌های برنامه، جهت سهولت استفاده‌ی از آن، در ابتدا فضای نام آن‌را به فایل سراسری Client\_Imports.razor اضافه می‌کنیم:
@using BlazorStateManagement.Stores.CounterStore
سپس تغییرات کامپوننت شمارشگر، جهت استفاده‌ی از سرویس ICounterStore، به صورت زیر خواهند بود:
@page "/counter"
@implements IDisposable

@inject ICounterStore CounterStore

<h1>Counter</h1>

<p>Current count: @CounterStore.GetState().Count</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    protected override void OnInitialized()
    {
        base.OnInitialized();
        CounterStore.AddStateChangeListener(UpdateView);
    }

    private void IncrementCount()
    {
        CounterStore.IncrementCount();
    }

    private void UpdateView()
    {
        StateHasChanged();
    }

    public void Dispose()
    {
        CounterStore.RemoveStateChangeListener(UpdateView);
    }
}
توضیحات:
- در اینجا در ابتدا سرویس ICounterStore، به کامپوننت تزریق شده‌است.
- سپس در متد رویدادگران آغازین OnInitialized، با استفاده از متد AddStateChangeListener، مشترک سرویس مخزن حالت شمارشگر شده‌ایم.
- همواره جهت پاکسازی کد و عدم اشتراک بیش از اندازه‌ی به یک مخزن حالت، نیاز است در پایان کار یک کامپوننت، با پیاده سازی implements IDisposable@، کار حذف اشتراک را انجام دهیم. در غیراینصورت هربار که کامپوننت بارگذاری می‌شود، یک اشتراک جدید از این کامپوننت، به مخزن حالتی که طول عمر Singleton دارد، اضافه خواهد شد که نشانی از نشتی حافظه‌است.
- دو قسمت دیگر را هم تغییر داده‌ایم. اینبار با استفاده از متد ()GetState، این Count اشتراکی را نمایش می‌دهیم و همچنین عمل به روز رسانی State را هم توسط متد IncrementCount انجام داده‌ایم.


در ادامه کامپوننت Client\Shared\NavMenu.razor را نیز جهت نمایش مقدار جاری Count، به صورت زیر به روز رسانی می‌کنیم:
@inject ICounterStore CounterStore

<li class="nav-item px-3">
   <NavLink class="nav-link" href="counter">
      <span class="oi oi-plus" aria-hidden="true"></span> Counter: @CounterStore.GetState().Count
   </NavLink>
</li>

@code {
    protected override void OnInitialized()
    {
        base.OnInitialized();
        CounterStore.AddStateChangeListener(() => StateHasChanged());
    }

    // ...
}
توضیحات:
- در اینجا نیز در ابتدا سرویس ICounterStore، به کامپوننت تزریق شده‌است.
- سپس در متد رویدادگران آغازین OnInitialized، با استفاده از متد AddStateChangeListener، مشترک سرویس مخزن حالت شمارشگر شده‌ایم و هربار که متد BroadcastStateChange ای توسط یکی از کامپوننت‌های متصل به مخزن حالت فراخوانی می‌شود (برای مثال در انتهای متد IncrementCount خود سرویس)، سبب اجرای Action آن که در اینجا StateHasChanged است، خواهد شد. فراخوانی StateHasChanged، کار اطلاع رسانی به UI، جهت رندر مجدد را انجام می‌دهد. به این ترتیب مقدار جدید Count توسط CounterStore.GetState().Count@ در منو نیز ظاهر خواهد شد:




کدهای کامل این مطلب را از اینجا می‌توانید دریافت کنید: BlazorStateManagement.zip
مطالب
تازه‌های سرویس پک یک VS 2010 ؛ یکپارچگی با IIS Express

در مورد تنظیمات دستی IIS Express که یک نسخه‌ی سبک IIS 7.5 قابل اجرا بر روی ویندوز XP نیز می‌باشد، پیشتر در این سایت مطلبی را مطالعه کرده‌اید (+). اکنون که سرویس پک یک VS 2010 ارائه شده (+)، دیگر نیازی به آن تنظیمات دستی نبوده و امکان استفاده یکپارچه و خودکار از این نسخه‌ی ساده شده IIS 7.5 به شرح زیر وجود دارد:

ابتدا نیاز است تا هر دو مورد سرویس پک یک VS 2010 و همچنین IIS Express به صورت جداگانه نصب شوند. سپس:

الف) ابتدا از منوی Tools‌ ، گزینه‌ی Options را انتخاب کنید. در صفحه‌ی باز شده در قسمت Projects and solutions ذیل گزینه‌ی Web projects نیاز است تا یکبار مجوز استفاده از IIS express صادر شود:



ب) اکنون بر روی نام پروژه در Solution explorer موجود در Visual studio کلیک راست کرده و گزینه‌ی Use IIS Express را انتخاب نمائید:



به این صورت تنظیمات لازم به صورت خودکار اعمال خواهد گردید و جهت مشاهده آن‌ها می‌توان به خواص پروژه، برگه‌ی Web مراجعه کرد:



نکته مهم:
نسخه‌ی RTM ویژوال استودیوی 2010 تنظیمات فوق را که در تصویر ملاحظه می‌کنید، ندارد. به عبارتی پس از اعمال تغییرات فوق باید دقت داشت سایرینی که قرار است از پروژه‌ی شما استفاده کنند نیز باید پیشنیازهای ذکر شده را رعایت نمایند و یا جهت توزیع سورس می‌توان مجددا بر روی نام پروژه کلیک راست کرده و اینبار گزینه‌ی Use Visual Studio Development Server قدیمی را انتخاب کرد.