اشتراک‌ها
تفاوت های int ، bigint ، smallint ، tinyint - در محاسبات مهم ، دقت کنید!!!
When you use the +, -, *, /, or % arithmetic operators to perform implicit or explicit conversion of int, smallint, tinyint, or bigint constant values to the float, real, decimal or numeric data types, the rules that SQL Server applies when it calculates the data type and precision of the expression results differ depending on whether the query is autoparameterized or not.
تفاوت های int ، bigint ، smallint ، tinyint  - در محاسبات مهم ، دقت کنید!!!
مطالب
بررسی کلمات کلیدی Const و ReadOnly در سی شارپ
تعریف: Constant فیلدی است که مقدار آن در زمان کامپایل (Compile time) مشخص می‌شود و این مقدار هیچگاه نمی‌تواند تغییر کند (ثابت است). از کلمه کلیدی (Keyword) ، const برای تعریف یک constant استفاده می‌شود.

  تعاریف اولیه :
Constant Field : فیلد ثابتی که مستقیما در یک Class و یا Struct تعریف می‌شود.
Constant Local : ثابتی که در بلاک‌های برنامه (بدنه یک تابع ، حلقه تکرار و ...) تعریف می‌شود.

همه‌ی انواع درون ساخت (Built in) در زبان #C مانند (انواع عددی، بولین، کاراکتر، رشته و نوع‌های شمارشی) و اشاره‌گرهای تهی (null reference) می‌توانند بصورت constant تعریف شوند. باید توجه داشت که عبارت تعریف و مقدار دهی یک constant (ثابت) باید بصورتی باشد که در زمان کامپایل کاملا قابل ارزیابی باشد.

جدول مقایسه‌ای بین Const و ReadOnly
Constant
ReadOnly
میتواند به Field‌ها و همچنین local‌‌ها اعمال شود. تنها به Field ها  اعمال می‌شود. 
مقدار دهی اولیه آن الزامی است. 
مقدار دهی اولیه می‌تواند هنگام تعریف و یا در درون سازنده انجام شود (در هیچ متد دیگری امکان پذیر نیست). 
 تخصیص حافظه انجام نمی‌شود و مقدار آن در کد‌های IL گنجانده می‌شود (توضیح در ادامه مطلب).   تخصیص حافظه بصورت داینامیک انجام می‌شود و می‌توانیم در زمان اجرا مقدار آن را بدست آوریم. 
 ثابت‌ها در #C بصورت پیش فرض از نوع static هستند. بدین معنا که از طریق نام کلاس  قابل دسترسی هستند.   تنها از طریق وهله سازی از یک کلاس قابل دسترسی هستند. 
 نوع‌های درون ساز (built in) و Null Reference ها  را می‌توان بصورت const تعریف کرد.
Boolean,Char, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal , string. 
مشابه Constant ها
مقدار آن در طول عمر یک برنامه ثابت است.
 مقدار آن می‌تواند در هنگام فراخوانی سازنده برای وهله‌های مختلف متفاوت باشد.
فیلد‌های const را نمی‌توان بصورت پارامتر‌های out و ref استفاده کرد.
فیلد‌های ReadOnly را می‌توان بصورت پارامتر‌های ref و out در درون سازنده استفاده کرد. 

نحوه تعریف یک constant :





همانطور که در تصویر مشاهده می‌کنید در کنار نماد انتخابی برای const‌ها یک قفل کوچک (نشان از غیرقابل تغییر بودن) قرار گرفته است .


مثالی از تعریف و رفتار Constant‌ها در #C :
const int field_constant = 10;  //constant field
static void Main(string[] args)
{
    const int x = 10, y = 15;   //constant local :correct
    const int z = x + y;        //constant local : correct;
    const int a = x + GetVariableValue();//Error
}
public static int GetVariableValue()
{
    const int localx = 10;
    return 10;
}
در خطوط اول و دوم ارزش متغیر‌های x,y,z بدرستی محاسبه و ارزیابی شده‌است. اما در خط سوم تخصیص مقدار برای ثابت a به زمان اجرای برنامه موکول شده است. در نتیجه با بروز خطا مواجه می‌شویم .

فیلد‌های فقط خواندنی ReadOnly


در #C فقط Field‌‌ها را می‌توان بصورت ReadOnly  تعریف کرد. این فیلد‌ها یا در زمان تعریف و یا از طریق سازنده مقدار دهی می‌شوند.






بررسی تفاوت readonly و  const در سطح IL

برای مشاهده کدهای سطح میانی (IL Code) از ابزار خط فرمان Developer Command ویژوال استدیو 2017 و همچنین برنامه ILdasm استفاده شده است. همانطور که در جدول مقایسه‌ای بیان شد، برای constant field ها  تخصیص حافظه‌ای صورت نمی‌گیرد و مقادیر مستقیما در کد‌های IL گنجانده می‌شود.
مثال: 
 class Program
    {
        public const int numberOfDays = 7;
        public readonly double piValue = 3.14;

        static void Main(string[] args)
        {
            
        }
    }












اگر فایل Exe کد فوق را توسط نرم افزار IL Dasm مشاهده کنید، خواهید دید که مقدار ذخیره شده در numberOfDays در کد IL گنجانده شده است : 








ولی مقدار ذخیره شده در piValue در زمان اجرا قابل دسترسی می‌باشد.






مشکل Versioning فیلدهای const
public const int numberOfDays = 7;
public readonly double piValue = 3.14;
اگر کد‌های فوق را به یک اسمبلی مجزا منتقل کنیم و از این کد‌ها در پروژه‌ای جدید استفاده کنیم، وضعیت Code ‌های IL به صورت زیر است:
کد برنامه اصلی که ارجاعی به اسمبلی جانبی دارد:
static void Main(string[] args)
{
   var readEx = new MyLib.TestClass();
   var readConstValue = MyLib.TestClass.numberOfDays;
   var readReadOnlyValue = readEx.piValue;
}
کد‌های IL :
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size 17 (0x11)
  .maxstack  1
  .locals init ([0] class [MyLib]MyLib.TestClass readEx,
  [1] int32 readConstValue,
  [2] float64 readOnlyValue)
  IL_0000:  nop
  IL_0001:  newobj   instance void [MyLib]MyLib.TestClass::.ctor()
  IL_0006:  stloc.0 //readEx
  IL_0007:  ldc.i4.7  //ارزش ذخیره شده در کد
  IL_0008:  stloc.1 //readConstValue
  IL_0009:  ldloc.0 //readEg
  IL_000a:  ldfld float64 [MyLib]MyLib.TestClass::piValue
  IL_000f:  stloc.2 //readReadOnlyValue
  IL_0010:  ret
} // end of method Program::Main
همانطور که می‌بینید ارزش ذخیره شده در کد IL، همان ارزشی است که در اسمبلی مجزا ذخیره شده است.
اگر در کتابخانه جانبی ارزش فیلد const را تغییر دهید و آن را مجدد کامپایل کنید، تا زمانیکه اسمبلی برنامه اصلی را کامپایل نکرده‌اید، همان ارزش قبلی در برنامه نمایش داده می‌شود.
برای غلبه بر این مشکل از فیلد‌های Static ReadOnly استفاده می‌کنیم.

مثال:
public class ReadonlyStatic
{
  public static readonly string x = "Hi";
  public static readonly string y;
  public ReadonlyStatic()
  {
     //y = "Hello"; This is wrong
  }
  static ReadonlyStatic()
  {
    y = "Hello";
  }
}

اولین مشکلی که با استفاده از فیلد‌های Static ReadOnly حل می‌شود، مشکل  Versioning فیلد‌های Const است. بدین ترتیب دیگر نیازی به کامپایل مجدد برنامه مصرف کننده نیست .
نکته بعدی که در کد فوق نشان داده شده‌است، فیلد‌های static readOnly در زمان تعریف و یا تنها از طریق سازنده‌ی static می‌توانند مقدار دهی شوند.

مقایسه ReadOnly و Static  :

ReadOnly
 Static
 هم در زمان تعریف و هم از طریق سازنده می‌توان آن را مقدار دهی کرد.   در زمان تعریف و تنها از طریق سازنده static می‌توان آن را مقدار دهی کرد.
مقدار بر اساس مقادیری که در سازنده‌ها تعیین می‌شود متفاوت است.
 مقادیر بعد از مقدار دهی اولیه تغییر نمی‌کنند. 


چه زمانی از Const و چه زمانی از ReadOnly استفاده کنیم :

  • زمانی باید از Const استفاده کرد که مطمئن هستیم ارزش ذخیره شده در آن در طول عمر یک برنامه تغییر نمی‌کند. بطور مثال ذخیره تعداد روز هفته در یک فیلد از نوع Constant. اگر شک داریم که ممکن است این ارزش تغییر کند، می‌توانیم از حالت static readOnly برای غلبه بر مشکل Versioning استفاده کنیم.
  • از آنجائیکه مقادیر constant در کد‌های IL گنجانده می‌شوند، برای رسیدن به کارآیی بهتر، مقادیری را که در طول عمر یک برنامه تغییر نمی‌کنند، به صورت  const تعریف می‌کنیم.
  • هر زمان تصمیم داشتیم Constant هایی به ازای هر وهله از کلاس داشته باشیم از ReadOnly استفاده می‌کنیم. 
 
اشتراک‌ها
بوهای کد: جهش

We have a long, complex, difficult to understand method that is extremely hard to refactor under these circumstances. And that’s just looking at the mutability smells in code.

بوهای کد: جهش
نظرات مطالب
تفاوت بین IQueryable و IEnumerable در حین کار با ORMs
جالب بود. من هم چند وقت پیش به این موضوع برخورد کرده بودم: http://stackoverflow.com/questions/3949823/why-skip-and-take-does-not-work-when-passing-through-a-method

حتی یک مطلب کوچولو هم برای آن آماده کرده و در سیستم اتوماتیک وبلاگم برای انتشار گذاشته‌ام.
اشتراک‌ها
یک گرید ساده با قابلیت راست به چپ و پیجینگ در ری اکت
در این مقاله قصد دارم شمارو را با امکانات لایبرری "ری اکت انگرید " برای ری اکت جی اس آشنا کنم. این لایبرری شامل یک کامپوننت گرید با قابلیت‌های زیر هست:

1-ساپورت راست به چپ
2- نمایش پیجینگ
3-  نمایش لودر
4- امکان تغییر کلمات
5- امکان جاگذاری کامپوننت در هر سل

نحوه استفاده از این کامپوننت به این شکل هست:

1- تعریف ستونها:
const columns = [
    {
      field: "fullname",
      headerName: "First & last Name",
      description: "name of user",
      width: 50,
    },
    {
      field: "age",
      headerName: "Age",
      description: "age of user",
      width: 50,
      renderCell:(info)=><strong>Age is : {info.data.age}</strong>
    }
]

2- تعریف استیت‌های لازم برا ست کردن سطر ها، لودر، تعداد کل, شماره صفحه و بزرگی هر صفحه(دقت شود که امکان استفاده بدون پیجینگ هم وجود دارد و امکانات کامل را در لینک لایبرری میتوانید مطالعه نمایید) 
...
const [rows,setRows] = useState([]);
const [loading,setLoading] = useState(false);
const [totalCount,setTotalCount] = useState(0);
const [filter,setFilter] = useState({ pageSize:10, pageNumber:1 });
const _fetchData = async () => { if (!active) return; //mock api, you can call your api then set data to table like commented line below return new Promise((resolve) => { setLoading(true); setTimeout(() => { setRows(data);// SetRows, note that data comes from api and must be array of objects setTotalCount(7);//=== set total page size for pagination part resolve(); setLoading(false); }, 2000); }); }
3- در نهایت کامپوننت مورد نظر:
import Angrid from "rect-angrid";
...
_handlePageChange = (newPage)=>{
    setFilter(p=>({...p,pageNumber:newPage}))
}
...
      <AnGrid
        loading={loading}
        columns={columns}
        rows={rows}
        showRowNumber={true}
        pageSize={filter.pageSize}
        pageNumber={filter.pageNumber}
        totalCount={totalCount}
        onPageChange={_handlePageChange}
        theme="dark"
        minHeight={300}
        emptyList={<strong>There Is No Info</strong>}
      />
نمایی از گرید:



یک گرید ساده با قابلیت راست به چپ و پیجینگ در ری اکت
اشتراک‌ها
سرویس های gRPC در ASP.NET Core

Originally developed at Google, gRPC today is a remote procedure call (RPC) framework that has emerged as an alternative to RESTful and HTTP-based interfaces to connect remote components and specifically microservices. The new RPC framework was created in part to work with modern technologies such as HTTP/2 and Protobuf. 

سرویس های gRPC در ASP.NET Core
مطالب
بررسی کارآیی کوئری‌ها در 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 نمایش داده نشود و وقت و منابع را تلف نکند. بدیهی است پس از پایان کار بررسی آماری، نیاز به عدم انتخاب این گزینه خواهد بود.
اشتراک‌ها
در آینده‌ی JavaScript کمتر از خود JavaScript استفاده خواهد شد

I can tell at least that in 3 years, JavaScript will gain more the status of a VM and lose the status of a language. Already today, not many people use raw JavaScript. You usually have some transpilation, at least e.g. Babel. In the future, Web Assembly will enable more innovation in that regards, and existing transpiling languages like Elm, TypeScript, PureScript will continue to improve. 

در آینده‌ی JavaScript کمتر از خود JavaScript استفاده خواهد شد
اشتراک‌ها
یادگیری SASS در 15 دقیقه

If you write copious amounts of CSS, a pre-processor can greatly decrease your stress levels and save you a lot of precious time. Using tools such as Sass, Less, Stylus or PostCSS makes large and complicated stylesheets clearer to understand and easier to maintain. Thanks to features like variables, functions and mixins the code becomes more organized, allowing developers to work quicker and make less mistakes. 

یادگیری SASS در 15 دقیقه
اشتراک‌ها
Strongly typed AppSettings Configuration در ASP.NET 5
The configuration system in ASP.NET 5 has been completely overhauled and entire web.config/app.config mechanism has been thrown out in favor of a new pluggable system. The default configuration implementation uses a config.json file as storage, but the system is pluggable so other providers can be used instead as well as at the same time. For example, the default project template uses both config.json and environment variables, the latter of which override values in the .json file. 
Strongly typed AppSettings Configuration در ASP.NET 5