راهنماهای پروژه‌ها
اعداد فارسی در گزارشات
عموما برای نمایش اعداد فارسی در گزارشات، از فونت‌های فارسی تغییر یافته استفاده می‌شود. برای مثال فونت irsans ایی که در پوشه bin مثال‌های پروژه هست، از این نوع است. فونت‌های معمولی را در یک فونت ادیتور باز می‌کنند و بجای اعداد انگلیسی آن، معادل اعداد فارسی موجود در همان فایل فونت را کپی و پیست می‌کنند. این روش از قدیم برای ساخت گزارشات فارسی کاربرد داشته است.

یک نکته: (خصوصا در جایی که Font از نوع System.Drawing.Font مورد نیاز است؛ مثلا در حین تولید نمودارهای MS Chart)
اگر فونت مورد نظر بر روی سرور نصب نیست، به این صورت هم قابل بارگذاری است:
var privateFontCollection = new PrivateFontCollection();    
privateFontCollection.AddFontFile(fontPath);
var fontFamily = privateFontCollection.Families[0];
var font = new Font(fontFamily); 
البته لازم به ذکر است که روش دیگر فرمت مقادیر نمایش داده شده، تنظیم DisplayFormatFormula است. یک مثال کاربردی در این زمینه: (^)
اشتراک‌ها
نمایش فایل PDF بر روی وب

نمی دانم به چه دلیل دیگر PDF.Js بر روی مروگر کروم (موارد دیگر را تست نکردم) امکان مشاهده PDF در وب را نمی‌دهد اما در لینک این خبر راه‌های دیگر مشاهده  PDF را می‌توانید ببینید.

من از آپلودر بوت استرپی  استفاده میکنم که امکان مشاهده PDF  و Word و Excel و تصویر  میدهد برای مشاهده pdf با مشکل مواجه شده بود که به کمک گوگل درایو توانستم فایل‌های PDF آپلود شده را نمایش بدهم.

نمایش فایل PDF بر روی وب
نظرات مطالب
تعیین Fallback font برای قلم‌های فارسی در WPF
به این صورت کار می‌کنه:


<TextBlock 
            Text="نمایش مخلوطی از متن فارسی و متن English با هم"
            Margin="7"
            FontFamily="Fonts/irsans.ttf#Iranian Sans, Comic Sans Ms"
            FontSize="25"
            FlowDirection="RightToLeft"
            VerticalAlignment="Top" HorizontalAlignment="Center"  />

نظرات مطالب
ارسال پارامتر از سی شارپ به مایکروسافت Word
در صورت نیاز به ویرایش اسناد در خود مرورگر، میتوان از کتابخانه text control  استفاده کرد که عملا به شما یک نرم افرار word تحت وب میده.
همچنین قابلیت merge کردن data source‌های متفاوتی رو با قالب بارگذاری شده داره.
جایگزینی براش نیست واقعا ولی برای موارد open source، بجز OpenXmlWordHelper میتوان از کتابخانه Aspose  هم برای جایگزینی پارامتر در یک فایل ورد استفاده کرد. 
نظرات مطالب
آشنایی با WebDav و نحوه استفاده از آن
سلام. با تشکر از آموزش و تهیه کتابخونه.

وقتی فایل رو با word باز میکنم، بصورت readonly باز میشه و گزینه save بصورت آیکن sync نیست.
هم توی نمونه سورس کد گیت و هم یک وب‌اپ که خودم ایجاد کردم و رفرنس و پکیج نصب کردم مشکل بود. روی iis هم پابلیش گذاشتم فرقی نکرد.
پاسخ به بازخورد‌های پروژه‌ها
ایجاد یک گزارش تمام صفحه از چارت بدون رکورد
لطفا به این دو مطلب مراجعه نمائید:
- قرار دادن جدول و چارت با هم : «قرار دادن نمودارهای MS Chart در گزارشات PdfReport»
- فقط قرار دادن چارت در فایل PDF :
 «Microsoft Chart Controls to PDF with iTextSharp and ASP.NET MVC »

مطالب
ارسال پارامتر از سی شارپ به مایکروسافت Word
فرض کنید نامه‌ای را می‌خواهیم تنظیم کنیم. سمت برنامه، شماره، تاریخ و نام مدیر عامل و ... را مشخص می‌کنیم و می‌خواهیم این اطلاعات را به ورد بفرستیم؛ همچنین متن نامه را هم در ورد تایپ کنیم و در آخر هم نامه را آرشیو کنیم. برای اینکار چندین روش وجود دارد. ما در این مقاله از روش MailMergeField و Bookmark استفاده میکنیم.

روش ایجاد الگوهای Word

ابتدا می‌خواهیم یک الگو یا Template را درست کنیم و بعد‌ها از روی آن، نامه‌ی جدیدی را ایجاد کنیم و فیلدهایش را پرکنیم. برای اینکار یک سند جدید را در Word ایجاد و به سربرگ Mailings مراجعه میکنیم. سپس دکمه‌ی Select Recipients را بزنید. در ادامه از منوی باز شده، Type a NewList را بزنید. با اینکار پنجره‌ای باز می‌شود. در اینجا دکمه‌ی Customize Columns را بزنید. این پنجره شامل فیلدهایی می‌شود که میتوانید از آن استفاده کنید و بر روی سند قرار دهید و داخل برنامه با پیدا کردن این فیلدها میتوانید بجای آن‌ها، مقدار مورد نظرتان را پاس دهید. حالا شما نیاز دارید تا از طریق دکمه‌ی Add، تمامی فیلدهای لازم یک نامه را بسازید. پس از این کار، در هر دو پنجره ، دکمه‌ی OK را بزنید. بدین صورت یک پنجره‌ی ذخیره برای شما باز می‌شود تا این فیلدهایی  را که ایجاد کردید، به عنوان یک دیتابیس کوچک ذخیره شود که تمامی فیلدها را دارا می‌باشد و هر موقع که خواستید دوباره میتوانید از همین فیلد‌ها استفاده کنید.

حالا می‌رسیم به قرار دادن این فیلد‌ها داخل سند. با ذخیره کردن فیلدها، تمامی گزینه‌های سربرگ Mailings فعال می‌شود. شما برای اینکه فیلدی را بر روی سند قرار دهید، روی Insert Merge Field کلیک و متناسب با نیازتان، فیلدها را قرار دهید و الگو را طراحی کنید. یک نمونه:


حالا فایل را با پسوند DOT. ذخیره کنید. در ادامه این فایل را در دیتابیس، به این روش ذخیره کنید: 

String FilePath = "Template Path"
// Converting File to ByteArray
byte[] FileBuffer = System.IO.File.ReadAllBytes(FilePath);
// Now you can insert this file buffer to DB

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


روش ارسال پارامترها به الگوهای Word

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

بنابراین در ادامه ابتدا Assembly مربوط به MicroSoft.Office.Interop.Word را به رفرنس‌های پروژه اضافه میکنیم و سربرگش را هم Using میکنیم.


حالا می‌رسیم به کد نویسی:

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

//LOCATION OF THE TEMPLATE FILE ON THE MACHINE;
Object oTemplatePath = string.Format("{0}\\NewDocument.dot", Application.StartupPath);
 
//OBJECT OF MISSING "NULL VALUE"
Object oMissing = System.Reflection.Missing.Value;
 
//OBJECTS OF FALSE AND TRUE
Object oTrue = true;
Object oFalse = false;
 
//CREATING OBJECTS OF WORD AND DOCUMENT
Microsoft.Office.Interop.Word.Application oWord = null;
Microsoft.Office.Interop.Word.Document oWordDoc = null;

سپس کدهای زیر را داخل رخ‌داد گردان کلیک دکمه‌ی مثلا "پیشنمایش" مینویسیم:
// Fetching Template ByteArray From Database => Byte[] YourTemplateByteArray = Fetch Template;

System.IO.File.WriteAllBytes(oTemplatePath.ToString(), YourByteArray);

oWord = new Microsoft.Office.Interop.Word.Application();
oWordDoc = new Microsoft.Office.Interop.Word.Document();

//Adding A New Document From A Template
oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);

int iTotalFields = 0;
// Finding Mailmerge Fields
foreach(Microsoft.Office.Interop.Word.Field myMergeField in oWordDoc.Fields) {
  iTotalFields++;
  Microsoft.Office.Interop.Word.Range rngFieldCode = myMergeField.Code;
  String fieldText = rngFieldCode.Text;

  // Only Get The Mailmerge Fields
  if (fieldText.StartsWith(" MERGEFIELD")) {
    // Gives The Fieldnames as Entered in .DOT File
    string fieldName = fieldText.Substring(12, fieldText.IndexOf(" ", 12) - 12);

    switch (fieldName) {
    case "Letter_No":
      myMergeField.Select();
      oWord.Selection.TypeText(txtLetterNo.Text);
      break;

    case "Letter_Date":
      myMergeField.Select();
      oWord.Selection.TypeText(DateTime.Now);
      break;

    case "Letter_Has_Attachment":
      myMergeField.Select();
      oWord.Selection.TypeText("دارد یا ندارد");
      break;

      // And So On
    default:
      break;
    }
  }
}

//Showing The Document To The User
oWord.Visible = true;

در ادامه یک دکمه را برای ذخیره‌ی فایل ورد قرار می‌دهیم. زمانیکه کاربر تایپ کردنش تمام شد و هنوز برنامه‌ی ورد در حال اجراست، این دکمه را اجرا می‌کند. دقت کنید برنامه‌ی ورد نباید بسته شود؛ باید باز باشد. بعد دکمه‌ی ذخیره را می‌زنیم. با کدنویسی، برنامه‌ی Word را خودمان می‌بندیم؛ نیازی به دخالت کاربر نیست. 

oWordDoc.Save();

//Closing the file
oWordDoc.Close(ref oFalse, ref oMissing, ref oMissing);

//Quitting the application
oWord.Quit(ref oMissing, ref oMissing, ref oMissing);
byte[] FileBuffer = System.IO.File.ReadAllBytes(oTemplatePath.ToString  ());
 
// Now Insert The FileBuffer Into Database as A Letter


خوب؛ کار تمام است! حالا فیلد FileBuffer را باید بسته به کدنویسی خودتان، داخل دیتابیس ذخیره کنید که برای بعدها بتوانید آن‌را واکشی کرده و به کاربر نمایش دهید. این هم نمونه‌ی نهایی جایگذاری فیلدها: 


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

مطالب
بررسی کارآیی کوئری‌ها در SQL Server - قسمت اول - جمع آوری اطلاعات آماری کوئری‌های زنده
بسیاری از شرکت‌ها دارای نقشی مانند «مدیران بانک اطلاعاتی» نیستند؛ اما تعدادی «توسعه دهنده‌ی بانک‌های اطلاعاتی» را به همراه دارند که گاهی از اوقات از آن‌ها خواسته می‌شود تا کارآیی پایین کوئری‌های صورت گرفته را بررسی و رفع کنند و ... آن‌ها دقیقا نمی‌دانند که باید از کجا شروع کنند! فقط می‌دانند که یک کوئری، مدت زمان زیادی را برای اجرا به خود اختصاص می‌دهد؛ اما نمی‌دانند که چگونه باید به کوئری پلن آن دسترسی یافت و چگونه باید آن‌را تفسیر کرد. در این حالت حداکثر کاری را که ممکن است انجام دهند، افزودن یک ایندکس جدید است که ممکن است کار کند و یا خیر و حتی اگر کار کند، دقیقا نمی‌دانند که چگونه! هدف از این سری، بررسی مقدماتی روش‌های بهبود کارآیی کوئری‌ها در SQL Server، از دید یک «توسعه دهنده‌ی بانک‌های اطلاعاتی» است.


پیشنیازهای این سری

در این سری از بانک اطلاعاتی استاندارد مثال به همراه SQL Server 2016، به نام WideWorldImporters استفاده می‌کنیم. برای دریافت آن، به قسمت releases مثال‌های مایکروسافت مراجعه کرده و فایل WideWorldImporters-Full.bak را دریافت کنید. پس از دریافت این فایل، برای restore سریع آن، می‌توانید دستور زیر را اجرا کنید که در آن باید مسیر فایل bak دریافتی و همچنین مسیر ایجاد فایل‌های mdf/ldf/ndf را مطابق مسیرهای سیستم خودتان اصلاح نمائید (فقط مسیر پوشه‌ها را نیاز است تغییر دهید):
use master;

RESTORE DATABASE WideWorldImporters 
FROM disk='D:\path\WideWorldImporters-Full.bak'
WITH MOVE 'WWI_Primary' TO 'D:\SQL_Data\WideWorldImporters.mdf',
MOVE 'WWI_Log' TO 'D:\SQL_Data\WideWorldImporters_log.ldf',
MOVE 'WWI_UserData' TO 'D:\SQL_Data\WideWorldImporters_UserData.ndf',
MOVE 'WWI_InMemory_Data_1' TO 'D:\SQL_Data\WideWorldImporters_InMemory_Data_1'
همچنین صرفنظر از نگارش SQL Server ای که در حال استفاده‌ی از آن هستید (البته به حداقل SQL Server 2016 نیاز خواهید داشت)، بهتر است آخرین نگارش برنامه‌ی management studio را نیز به صورت مستقل دریافت و نصب کنید که در این زمان نگارش 18.1 است.


یافتن اطلاعاتی در مورد کوئری‌ها

SQL Server زمانیکه یک کوئری را اجرا می‌کند، اطلاعاتی را نیز به همراه آن تولید خواهد کرد که سبب ایجاد یک Query Plan می‌شود و در آن، اطلاعاتی مانند جداول مورد استفاده، نوع جوین‌ها، ایندکس‌های استفاده شده و غیره وجود دارند. علاوه بر آن، Query Statistics نیز قابل دسترسی هستند که در آن مدت زمان اجرای یک کوئری، میزان I/O صورت گرفته و میزان مصرف CPU کوئری، ذکر می‌شوند. برای دسترسی یافتن به این اطلاعات، می‌توان به اشیاء مختلف SQL Server مراجعه کرد؛ مانند dynamic management objects یا به اختصار DMO's، همچنین extended events، traces، query stores و یا حتی management studio. مهم‌ترین تفاوت این‌ها نیز در نحوه‌ی دسترسی به اطلاعات آن‌ها است که می‌تواند زنده (live) و یا ذخیره شده در جائی باشند. در اینجا تنها منبعی که امکان مشاهده‌ی این اطلاعات را به صورت زنده میسر می‌کند، management studio است. البته live در اینجا به معنای امکان مشاهده‌ی تمام اطلاعات مرتبط با یک کوئری، مانند آمار و کوئری پلن آن در داخل محیط management studio، پس از اجرای یک کوئری است. در این قسمت بیشتر به روش استخراج اطلاعات آماری کوئری‌های زنده می‌پردازیم و در قسمت‌های بعدی، سایر گزینه‌های نامبرده شده را نیز بررسی خواهیم کرد.


مشاهده‌ی زنده‌ی داده‌های مرتبط با اجرای یک کوئری در management studio

پس از restore بانک اطلاعاتی مثال WideWorldImporters که عنوان شد، در برنامه‌ی Microsoft SQL Server Management Studio، کوئری زیر را اجرا می‌کنیم:
USE [WideWorldImporters];
GO

SELECT
    [s].[StateProvinceName],
    [s].[SalesTerritory],
    [s].[LatestRecordedPopulation],
    [s].[StateProvinceCode]
FROM [Application].[Countries] [c]
    JOIN [Application].[StateProvinces] [s]
    ON [s].[CountryID] = [c].[CountryID]
WHERE [c].[CountryName] = 'United States';
GO
با اجرای آن، اگر به ذیل ردیف‌های بازگشت داده شده‌ی در Management Studio دقت کنیم، مشخص کرده‌است که این کوئری، 53 ردیف را بازگشت داده و همچنین کمتر از 1 ثانیه مدت زمان اجرای آن، طول کشیده‌است:


اینجا است که نیاز به اطلاعات بیشتری در مورد نحوه‌ی اجرای این کوئری داریم. برای استخراج این اطلاعات، اینبار گزینه‌های تولید و جمع آوری اطلاعات آماری IO و TIME را روشن می‌کنیم و سپس همان کوئری قبلی را اجرا خواهیم کرد:
USE [WideWorldImporters];
GO

SET STATISTICS IO ON;
GO
SET STATISTICS TIME ON;
GO

SELECT
    [s].[StateProvinceName],
    [s].[SalesTerritory],
    [s].[LatestRecordedPopulation],
    [s].[StateProvinceCode]
FROM [Application].[Countries] [c]
    JOIN [Application].[StateProvinces] [s]
    ON [s].[CountryID] = [c].[CountryID]
WHERE [c].[CountryName] = 'United States';
GO
ظاهر اجرای این کوئری با کوئری قبلی، تفاوت خاصی ندارد. اما اگر در همینجا به برگه‌ی messages، که در کنار برگه‌ی results و نمایش ردیف‌ها قرار دارد، مراجعه کنیم، یک چنین خروجی قابل مشاهده است:
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 504 ms.

(53 rows affected)
Table 'Countries'. Scan count 0, logical reads 118, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'StateProvinces'. Scan count 1, logical reads 43, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 10 ms.
در اینجا اطلاعات آماری مدت زمان کامپایل و همچنین مدت زمان اجرای کوئری، ارائه شده‌اند. به علاوه در میانه‌ی این آمار، اطلاعات IO کوئری مانند logical reads درج شده‌اند.


استخراج اطلاعات Actual Execution Plan یک کوئری

کوئری را زیر با فرض IO ON و TIME ON حاصل از اجرای کوئری قبل، اجرا می‌کنیم:
USE [WideWorldImporters];
GO

SET STATISTICS XML ON;
GO

SELECT
    [s].[StateProvinceName],
    [s].[SalesTerritory],
    [s].[LatestRecordedPopulation],
    [s].[StateProvinceCode]
FROM [Application].[Countries] [c]
    JOIN [Application].[StateProvinces] [s]
    ON [s].[CountryID] = [c].[CountryID]
WHERE [c].[CountryName] = 'United States';
GO

SET STATISTICS XML OFF;
GO
با فعالسازی اطلاعات آماری XML (و خاموش کردن آن در انتهای کار)، اینبار در برگه‌ی messages، اطلاعات بیشتری ارائه شده‌اند:
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 7 ms.

(53 rows affected)
Table 'Countries'. Scan count 0, logical reads 118, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'StateProvinces'. Scan count 1, logical reads 43, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 15 ms,  elapsed time = 179 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
اگر دقت کنید اینبار زمان اجرا اندکی بیشتر شده‌است؛ چون درخواست تهیه‌ی query plan را داده‌ایم. این plan را در ذیل قسمت نتایج کوئری می‌توان مشاهده کرد:


اگر بر روی این XML کلیک کنیم، برگه‌ی جدید نمایش گرافیکی این plan ظاهر می‌شود:


با کلیک راست بر روی این برگه، می‌توان اطلاعات آن‌را جهت بررسی‌های بعدی و یا به اشتراک گذاری آن ذخیره کرد.
در این plan اگر اشاره‌گر ماوس را بر روی هر کدام از عناصر آن حرکت دهیم، اطلاعاتی مانند actual number of rows نیز مشاهده می‌شود، در کنار اطلاعات تخمینی؛ به همین جهت به آن Actual Execution Plan هم گفته می‌شود.


این یک روش دسترسی به Execution Plan است. روش دوم آن با استفاده از امکانات رابط کاربری خود Management Studio است؛ با فشردن دکمه‌های Ctrl+M و یا انتخاب گزینه‌ی Include actual execution plan از منوی Query آن. پس از آن کوئری زیر را اجرا کنید:
SET STATISTICS IO ON;
GO
SET STATISTICS TIME ON;
GO

SELECT
    [s].[StateProvinceName],
    [s].[SalesTerritory],
    [s].[LatestRecordedPopulation],
    [s].[StateProvinceCode]
FROM [Application].[Countries] [c]
    JOIN [Application].[StateProvinces] [s]
    ON [s].[CountryID] = [c].[CountryID]
WHERE [c].[CountryName] = 'United States';
GO
اینبار در برگه‌ی نتایج کوئری، برگه‌ی سوم Execution Plan قابل مشاهده‌است:




استخراج اطلاعات Estimated Execution Plan یک کوئری

تا اینجا نحوه‌ی استخراج اطلاعات Actual Execution Plan را بررسی کردیم که به همراه اطلاعات دقیق حاصل از اجرای کوئری نیز بود؛ مانند actual number of rows. نوع دیگری از Execution Planها را نیز می‌توان از SQL Server درخواست کرد که به آن‌ها Estimated Execution Plan گفته می‌شود و حاصل اجرای کوئری نیستند؛ بلکه تخمینی هستند از روش اجرای این کوئری توسط SQL Server. برای فعالسازی محاسبه‌ی آن، ابتدا کوئری زیر را در management studio انتخاب کنید:
USE [WideWorldImporters];
GO

SELECT
    [s].[StateProvinceName],
    [s].[SalesTerritory],
    [s].[LatestRecordedPopulation],
    [s].[StateProvinceCode]
FROM [Application].[Countries] [c]
    JOIN [Application].[StateProvinces] [s]
    ON [s].[CountryID] = [c].[CountryID]
WHERE [c].[CountryName] = 'United States';
GO
سپس از منوی Query، گزینه‌ی Display estimated execution plan را انتخاب نمائید و یا دکمه‌های Ctrl+L را فشار دهید. در این حالت برگه‌های حاصل، حاوی قسمت results نیستند؛ چون کوئری اجرا نشده‌است. اما هنوز برگه‌ی Execution Plan قابل مشاهده است:


همانطور که مشاهده می‌کنید، اینبار نتیجه‌ی حاصل، به همراه اطلاعاتی مانند actual number of rows نیست و صرفا تخمینی است از روش اجرای این کوئری، توسط SQL Server.


جمع آوری اطلاعات آماری کلاینت‌ها

در منوی Query، گزینه‌ای تحت عنوان Include client statistics نیز وجود دارد. با انتخاب آن، اگر کوئری زیر را اجرا کنیم:
USE [WideWorldImporters];
GO

SELECT
    [s].[StateProvinceName],
    [s].[SalesTerritory],
    [s].[LatestRecordedPopulation],
    [s].[StateProvinceCode]
FROM [Application].[Countries] [c]
    JOIN [Application].[StateProvinces] [s]
    ON [s].[CountryID] = [c].[CountryID]
WHERE [c].[CountryName] = 'United States';
GO
اینبار برگه‌ی جدید client statistics ظاهر می‌شود:


در اینجا مشخص می‌شود که آیا عملیات insert/update/delete انجام شده‌است. چه تعداد ردیف تحت تاثیر اجرای این کوئری قرار گرفته‌اند. چه تعداد تراکنش انجام شده‌است. همچنین اطلاعات آماری شبکه و زمان نیز در اینجا ارائه شده‌اند.
در همین حالت، کوئری جدید زیر را با تغییر قسمت where کوئری قبلی، اجرا کنید:
SELECT
    [s].[StateProvinceName],
    [s].[SalesTerritory],
    [s].[LatestRecordedPopulation],
    [s].[StateProvinceCode]
FROM [Application].[Countries] [c]
    JOIN [Application].[StateProvinces] [s]
    ON [s].[CountryID] = [c].[CountryID]
WHERE [s].[StateProvinceName] LIKE 'O%';
GO
نتیجه‌ی آن، ظاهر شدن ستون جدید trial 2 است که می‌تواند جهت مقایسه‌ی کوئری‌های مختلف با هم، بسیار مفید باشد:


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


عدم نمایش ردیف‌های بازگشت داده شده‌ی توسط کوئری در حین جمع آوری اطلاعات آماری

هربار اجرای یک کوئری در management studio، به همراه بازگشت و نمایش ردیف‌های مرتبط با آن کوئری نیز می‌باشد. اگر می‌خواهید در حین بررسی کارآیی کوئری‌ها از نمایش این ردیف‌ها صرف نظر کنید (تا بار این برنامه کاهش یابد)، می‌توانید از منوی Query، گزینه‌ی Query Options را انتخاب کرده و در قسمت Results، گزینه‌ی Grid آن، گزینه‌ی discard results after execution را انتخاب کنید تا دیگر برگه‌ی results نمایش داده نشود و وقت و منابع را تلف نکند. بدیهی است پس از پایان کار بررسی آماری، نیاز به عدم انتخاب این گزینه خواهد بود.
راهنماهای پروژه‌ها
چگونه فایل‌های PDF را نمایش دهیم؟
بهترین نمایشگر فایل‌های PDF بدون شک نرم افزار رایگان Adobe Reader است. پس از نصب این برنامه، Active-X همراه آن در انواع و اقسام برنامه‌ها و حتی صفحات وب نیز قابل استفاده است. برای نمونه به دو مطلب ذیل در سایت مراجعه نمائید:
استفاده از کنترل‌های Active-X در WPF  
نمایش یک فایل PDF در WinForms ، WPF و سیلورلایت

همچنین روش‌های دیگری که عموما مبتنی بر تبدیل PDF به تصویر هستند نیز جهت نمایش فایل‌های PDF کاربرد دارند. در لینک ذیل، جمع آوری مطالب مرتبطی را خواهید یافت:
iTextSharp

به علاوه مرورگرهای مدرن نیز در پی ارائه پشتیبانی توکاری از نمایش فایل‌های PDF هستند. برای نمونه می‌توان به پروژه PDF.js فایرفاکس که از نگارش 15 آن جرئی از فایرفاکس شده است، اشاره کرد.