نظرات مطالب
مروری بر کاربرد DoEvents
در wpf هم مشکل freez شدن UI وجود دارد با این تفاوت که استفاده از DoEvents امکان پذیر نیست و راه حل‌های مشابه هم چندان چنگی به دل نمی‌زنند. آیا راهی اصولی برای wpf وجود دارد؟
مطالب
روش بازگشت به قالب‌های کلاسیک پروژه‌ها در دات نت 6
نگارش نهایی دات نت 6، حدود یک ماه دیگر منتشر می‌شود و اگر برای نمونه RC2 آن‌را نصب کرده باشید، با ایجاد یک پروژه‌ی کنسول جدید مبتنی بر آن ... شگفت زده خواهید شد!  شاید انتظار داشته باشید که با چنین فایلی مواجه شوید:
using System; 
 
namespace MyVerboseApp 
{ 
    public class Program 
    { 
        public static void Main(string[] args) 
        { 
            Console.WriteLine("Hello World!"); 
        } 
    } 
}
اما یک چنین خروجی تولید می‌شود:
 // See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
این مورد قابلیتی است که به همراه C# 9.0 به نام «Top Level Programs» ارائه شد و اکنون در تمام قالب‌های پیش‌فرض پروژه‌های مبتنی بر دات نت 6، استفاده شده‌است. این قالب شاید برای تازه‌کارها، جالب باشد و کم حجم و کم سطر، اما «ما آن‌را درخواست نداده بودیم!».


روش بازگشت به قالب‌های قبلی

در حال حاضر و در نگارش فعلی و حتی رسمی دات نت 6، روشی برای بازگشت به حالت قبلی وجود ندارد که به احتمال زیاد در نگارش‌های پس از RTM لحاظ خواهد شد (می‌توانید در اینجا ^ و ^ به آن رای دهید). تنها راه حل موجود، استفاده از دستور زیر است:
dotnet new console --framework net5.0 --target-framework-override net6.0
این دستور در اصل به این معنا است که پروژه‌ی من را بر اساس قالب پروژه‌های NET 5.0. تولید کن؛ اما در فایل csproj آن، بجای net5.0 از net6.0 به عنوان target framework استفاده شود:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
    <OutputType>Exe</OutputType>
-    <TargetFramework>net5.0</TargetFramework>
+    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>
</Project>
در اینجا سطر net5.0 را حذف و با net6.0 جایگزین کنید.
مطالب
معرفی افزونه‌های مفید VSCode جهت کار با Angular
VSCode یکی از بهترین ادیتورهایی است که از آن می‌توان برای توسعه‌ی برنامه‌های Angular استفاده کرد و در این بین افزونه‌های ویژه‌ای جهت کار با Angular برای آن تدارک دیده شده‌اند که در ادامه تعدادی از مهم‌ترین‌های آن‌ها را بررسی می‌کنیم.


Angular Essentials

این افزونه گروهی از مهم‌ترین افزونه‌های موجود را به صورت بسته بندی شده ارائه می‌دهد و با نصب آن، تعدادی از افزونه‌هایی را که در ادامه نامبرده خواهند شد، به صورت یکجا و خودکار دریافت خواهید کرد.


Angular Language Service

نگارش‌های اخیر Angular به همراه یک سرویس زبان نیز می‌باشند که به ادیتورهای مختلف این امکان را می‌دهد تا توسط این ویژگی بتوانند قابلیت‌های ویرایشی بهتری را جهت برنامه‌های Angular ارائه کنند. برای مثال ویرایش مطلوب قالب‌های کامپوننت‌های Angular و استفاده‌ی از Syntax خاص آن، موردی است که توسط هیچکدام از HTML ادیتورهای موجود پشتیبانی نمی‌شود. اکنون به کمک سرویس زبان Angular و افزونه‌ی ویژه‌ی آن برای VSCode که توسط تیم اصلی Angular توسعه یافته‌است، امکان ویرایش غنی قالب‌های HTML ایی آن فراهم شده‌است. این افزونه یک چنین قابلیت‌هایی را فراهم می‌کند:
الف) AOT Diagnostic messages
اگر قالب HTML ایی مورد استفاده (چه به صورت inline و چه در یک فایل html مجزا) به خاصیتی تعریف نشده اشاره کند، بلافاصله خطای مرتبطی ظاهر خواهد شد:


ب) Completions lists یا همان Intellisense
ج) امکان Go to definition با کلیک راست بر روی خواص و متدهای ذکر شده‌ی در قالب.
د) Quick info که با نزدیک کردن اشاره‌گر ماوس به خاصیت یا متدی در صفحه، اطلاعات بیشتری را در مورد آن نمایش می‌دهد.


angular2-inline

علاوه بر افزونه‌ی سرویس زبان‌های Angular، این افزونه نیز قابلیت درک قالب‌های inline کامپوننت‌ها را داشته و به همراه syntax highlighting و همچنین Intellisense است.


Auto Import

حین کار با TypeScript، هر ماژولی که در صفحه ارجاعی داشته باشد، باید در ابتدای فایل جاری import شود. افزونه‌ی Auto Import با بررسی ماژول‌های موجود و فراهم آوردن Intellisense ایی بر اساس آن‌ها، این‌کار را ساده‌تر می‌کند:


بنابراین این افزونه صرفا مختص به Angular نیست و برای کارهای متداول TypeScript نیز بسیار مفید است.


TSLint

این افزونه ابزار TSLint را با VSCode یکپارچه می‌کند. بنابراین نیاز است پیش از نصب این افزونه، وابستگی‌های ذیل را نیز به صورت سراسری نصب کرد:
 > npm install -g tslint typescript
کار TSLint انجام static code analysis است؛ چیزی شبیه به افزونه‌هایی مانند ری‌شارپر در ویژوال استودیو که راهنماهایی را در مورد بهتر کردن کیفیت کدهای نوشته شده ارائه می‌دهد.
تعدادی از امکانات آن‌را پس از نصب، با فشردن دکمه‌ی F1 می‌توان مشاهده کرد:


برای مثال تولید فایل tslint.json، امکان سفارشی سازی موارد بررسی شونده‌ی توسط این افزونه را فراهم می‌کند و اگر برنامه‌ی خود را توسط Angular CLI ایجاد کرده‌اید، این فایل هم اکنون در ریشه‌ی پروژه قرار دارد.
در مورد TSLint در مطلب «Angular CLI - قسمت دوم - ایجاد یک برنامه‌ی جدید» بیشتر توضیح داده شده‌است و اینبار به کمک این افزونه، خطاهای یاد شده را دقیقا درون محیط ادیتور و به صورت خودکار و یکپارچه‌ای مشاهده خواهید کرد.



Angular v4 TypeScript Snippets

سیستم کار VSCode مبتنی بر ایجاد فایل‌های خالی است و مفهوم قالب‌های از پیش آماده‌ی فایل‌ها در آن وجود ندارد. اما با کمک Code Snippets می‌توان این خلاء را پر کرد. افزونه‌ی Angular v4 TypeScript Snippets دقیقا به همین منظور طراحی شده‌است و زمانیکه حروف -a یا -rx را در صفحه تایپ می‌کنید، منویی ظاهر خواهد شد که توسط آن می‌توان قالب ابتدایی شروع به کار با انواع و اقسام جزئیات پروژه‌های Angular را تهیه کرد.



Path Intellisense

این افزونه مسیر فایل‌های موجود را به صورت یک Intellisense ارائه می‌کند و به این صورت به سادگی می‌توان مسیرهای اسکریپت‌ها و یا شیوه‌نامه‌ها را در ادیتور انتخاب و وارد کرد.

پاسخ به بازخورد‌های پروژه‌ها
خطای هم نامی خواص راهبری
کاربرد اینترفیس‌ها عموما به عنوان contract و قرار داد است و آنچنان استفاده عمومی جهت تعریف خواص یک کلاس مورد استفاده در EF یا ORMها را ندارد. من در مقالات متعددی که در مورد EF بررسی کردم، کسی navigation properties رو به صورت اینترفیس تعریف نمی‌کنه (به همین جهت این سؤال و جواب‌های متعدد فوق رخ داد). شاید بگردید در اینترنت یک در هزار یکی رو معرفی کنید، اما در حالت عمومی خیر.
بله، در حالت تعریف خواص یک کلاس که قرار است امکان تعریف قالب‌های متعددی توسط کاربر را داشته باشد، از اینترفیس‌ها هم ممکن است استفاده شود. در خود PdfReport در بسیاری از موارد از این روش استفاده شده. مثلا تعریف فونت آن یا بسیاری از سفارشی سازی‌های دیگر.
اما کار با ORMها یک سری اصول عمومی پذیرفته شده دارد و جهت تعریف خواص تو در توی کلاس‌های آن، استفاده از اینترفیس‌ها عمومیت ندارد.
شاید عنوان کنید که DI من کار تزریق وهله مورد نظر رو انجام می‌ده ولی .... خود ORM یک سربار است. DI هم سربار دوم. آیا کارآیی اینجا باید فدای طراحی نادرستی شود؟ استفاده از اینترفیس‌ها الزاما به معنای حرفه‌ای بودن یک طراحی نیست. بستگی داره کجا استفاده شدند. آیا قابلیت سفارشی سازی و افزونه پذیری رو ارائه می‌کنه؟ یا خیر؟
اشتراک‌ها
ویژگی های جدید Visual Studio 2017 15.8 Preview 3

Microsoft's release notes highlights for Preview 3 include:

  • Visual Studio now offers .NET Framework 4.7.2 development tools to supported platforms with 4.7.2 runtime included.
  • We improved performance during project unload/reload and branch switching.
  • With added support for Azure Functions, you now have a new target host in the Configure Continuous Delivery to Azure dialog.
  • Git and TFS status now updates properly for external file changes in .NET Core projects.
  • We added new productivity features, such as code cleanup, invert-if refactoring, Go to Enclosing Block, Multi-Caret support, and new keyboard profiles.
  • C++ enhancements include Template IntelliSense, convert macro to constexpr lightbulbs, and experimental in-editor code analysis squiggles.
  • You can now use cross-language debugging with Python 3.7.0rc1.
  • Performance Profiling now offers the ability to pause/resume data collection and adds a new .NET Object Allocation Tracking tool.
  • We included improvements for Android incremental builds in the Xamarinsupport for Xcode 9.4.
  •  
ویژگی های جدید Visual Studio 2017 15.8 Preview 3
مطالب
طریقه حذف Work item از Team Foundation Server
چنانچه برای مدیریت پروژه از Team Foundation Server استفاده می‌کنید، صرف نظر از اینکه نسخه اکسپرس یا کامل آنرا روی سرور نصب کرده اید و یا از نسخه رایگانی که مایکروسافت در آدرس http://tfs.visualstudio.com در اختیار کاربران قرار داده استفاده می‌کنید، یقیناً میدانید که Backlog item و Work item  می‌توانند در وضعیت‌های مختلفی قرار بگیرند. این وضعیت‌ها بسته به متدلوژی مورد استفاده، از لحاظ تعداد و یا عنوان با یکدیگر متفاوتند.
به عنوان مثال:
  • New
  • Approved
  • Committed
  • Done
  • Removed

در وضعیت‌های فوق چنانچه یک Work item اشتباهاً به Backlog افزوده شود، تنها راه اینکه اعلام کنیم این Work item از دستور کار خارج شده است، اینست که آنرا در وضعیت Removed قرار دهیم.

در هیچ کجای رابط کاربری (تحت وب و Team explorer در ویژوال استدیو) امکانی برای حذف یک Work item در نظر گرفته نشده است.

در ادامه روش حذف فیزیکی یک Work item از TFS را خواهیم دید:

1- ابتدا وارد خط فرمان (Command Prompt) شده و به مسیر زیر بروید:

cd %programfiles(x86)%\Microsoft Visual Studio 12.0\Common7\IDE
2- با استفاده از دستور witadmin بهمراه سوییچ destroywi، می‌توانید Work item مورد نظر را با استفاده از شناسه آن حذف کنید:
witadmin destroywi /collection:CollectionURL /id:id  
به عنوان مثال چنانچه آدرس CollectionURL پروژه شما https://mytfs.visualstudio.com/DefaultCollection و شناسه Work item مورن نظر 357 باشد، خواهیم داشت:
witadmin   destroywi   /collection:"https://mytfs.visualstudio.com/DefaultCollection "   /id:357   


چنانچه این قابلیت نظر شما را جلب کرد، توصیه می‌کنم نگاهی هم به سایر سوییچ‌های فرمان witadmin بیاندازید.
مطالب
تفاوت سیستم‌های یکپارچه با میکروسرویس‌ها (Monolithic vs Microservices architecture)

 معماری میکرو سرویس یا یکپارچه؟

برای درک میکروسرویس‌ها، باید بدانیم کاربرد سیستم‌های یکپارچه چیست و چه چیزی باعث شد در زمان‌های اخیر از برنامه‌های یکپارچه به میکروسرویس‌ها حرکت کنیم.


 سیستم‌های یکپارچه ( Monolithic applications  )

اگر تمام عملکردهای یک پروژه در یک بخش واحد وجود داشته باشند، آن برنامه به عنوان یک برنامه‌ی یکپارچه شناخته می‌شود. ما برنامه‌ی خود را در لایه‌های مختلفی مانند Presentation ، Service ، UI  طراحی می‌کنیم و سپس آن بخش از کدهای نوشته شده را به عنوان یک فایل خروجی به کار می‌گیریم. این چیزی نیست جز یک برنامه‌ی یکپارچه، که در آن " mono " یک پایگاه کد منفرد حاوی تمام عملکردهای مورد نیاز را نشان می‌دهد.


چرا اصلا به سمت میکروسرویس‌ها برویم؟

خب برای جواب به این سوال بهتر است معایب سیستم‌های یکپارچه را مرور کنیم:

  1. مدیریت دشوار بخاطر گسترش برنامه در گذشت زمان
  2. برای تغییری کوچک، کل برنامه را دوباره باید منتشر ( publish ) کنیم
  3. با تغییر و آپدیت برنامه، زمان انتشار افزایش می‌یابد.
  4. درک دشوار برای توسعه دهنده‌های جدید هر پروژه
  5. برای تقسیم ترافیک روی قسمت‌های مختلف برنامه، باید نمونه‌های کل برنامه را در چندین سرور منتشر کنیم که بسیار ناکارآمد و باعث استفاده‌ی بیهوده از منابع میشود
  6. اگر از فناوری یا تکنولوژی‌های جدید استفاده کنیم، برای عملکردی خاص، چه از نظر هزینه و چه از نظر زمان، بر کل برنامه تاثیر گذار است
  7. و در نهایت وجود یک باگ در هر ماژول میتواند کل برنامه را مختل کند.

و اما مزایای سیستم‌های یکپارچه:

  1. توسعه‌ی آن نسبت به میکروسرویس‌ها ساده است.
  2. انتشار آن آسان‌تر است؛ زیرا فقط یک خروجی، مستقر شده‌است.
  3. در مقایسه با معماری میکروسرویس‌ها، توسعه‌ی آن نسبتا آسان‌تر و ساده‌تر است.
  4. مشکلات تأخیر و امنیت شبکه در مقایسه با معماری میکروسرویس‌ها نسبتاً کمتر است.
  5. توسعه دهندگان نیازی به یادگیری برنامه‌های مختلف ندارند؛ آنها می‌توانند تمرکز خود را بر روی یک برنامه حفظ کنند.


میکروسرویس ها

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

معماری میکروسرویس تأثیر بسزایی در رابطه‌ی بین برنامه و پایگاه داده دارد. بجای اشتراک گذاری یک پایگاه داده با سایر میکروسرویس‌ها، هر میکروسرویس، پایگاه داده خاص خود را دارد که اغلب منجر به تکثیر برخی از داده‌ها می‌شود، اما اگر می‌خواهید از این معماری بهره مند شوید، داشتن یک پایگاه داده در هر میکروسرویس، ضروری است؛ زیرا اتصال ضعیف را تضمین می‌کند. مزیت دیگر داشتن یک پایگاه داده‌ی مجزا برای هر میکروسرویس این است که هر میکروسرویس می‌تواند از نوع پایگاه داده‌ای که برای نیازهای خود مناسب‌تر است، استفاده کند. هر سرویس یک ماژول را ارائه می‌دهد، به طوری که خدمات مختلف را می‌توان به زبان‌های برنامه نویسی مختلف نوشت. الگوهای زیادی در معماری میکروسرویس دخیل هستند مانند discovery و registry service ، Caching ، ارتباط API ، امنیت و غیره.



اصول میکروسرویس‌ها:

تک مسئولیتی: یکی از اصولی است که به عنوان بخشی از الگوی طراحی SOLID تعریف شده است. بیان می‌کند که یک Unit ، یا یک کلاس، یک متد یا یک میکروسرویس باید تنها یک مسئولیت را داشته باشد. هر میکروسرویس باید یک مسئولیت داشته باشد و یک عملکرد واحد را ارائه دهد. شما همچنین می‌توانید بگویید تعداد میکروسرویس‌هایی که باید توسعه دهید، برابر با تعداد عملکردهای مورد نیاز شما است. پایگاه داده نیز غیرمتمرکز است و به طور کلی، هر میکروسرویس، پایگاه داده خاص خود را دارد.

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

طراحی برای مدیریت خطاها: میکروسرویس‌ها باید با در نظر گرفتن مدیریت خطاها طراحی شوند. میکروسرویس‌ها باید از مزیت این معماری استفاده کنند و پایین آمدن یک میکروسرویس نباید بر کل سیستم تأثیر بگذارد و سایر عملکردها باید در دسترس کاربر باقی بمانند. اما در برنامه‌های کاربردی سیستم‌های یکپارچه که خطای یک ماژول منجر به سقوط کل برنامه می‌شود، اینگونه نبود.

مزایای میکروسرویس ها:

  1. مدیریت آن آسان است زیرا نسبتا کوچکتر است.
  2. اگر در یکی از میکروسرویس‌ها، بروزرسانی وجود داشته باشد، باید فقط آن میکروسرویس را مجدداً منتشر کنیم.
  3. میکروسرویس‌ها مستقل هستند و از این رو به طور مستقل منتشر می‌شوند. زمان راه اندازی و انتشار آنها نسبتاً کمتر است.
  4. برای یک توسعه‌دهنده جدید بسیار آسان است که وارد پروژه شود، زیرا او باید فقط یک میکروسرویس خاص را که عملکردی را که روی آن کار می‌کند، درک کند و نه کل سیستم را.
  5. اگر یک میکروسرویس خاص به دلیل استفاده بیش از حد کاربران از آن عملکرد، با بار زیادی مواجه است، ما باید فقط آن میکروسرویس را تنظیم کنیم. از این رو، معماری میکروسرویس از مقیاس بندی افقی پشتیبانی می‌کند.
  6. هر میکروسرویس بر اساس نیازهای تجاری می‌تواند از فناوری‌های مختلفی استفاده کند.
  7. اگر یک میکروسرویس خاص به دلیل برخی باگ‌ها از کار بیفتد، بر روی سایر میکروسرویس‌ها تأثیر نمی‌گذارد و کل سیستم دست نخورده باقی می‌ماند و به ارائه سایر عملکردها به کاربران ادامه می‌دهد.

معایب میکروسرویس ها:

  1. پیچیده است و پیچیدگی آن با افزایش تعداد ریز سرویس‌ها افزایش می‌یابد.
  2. نیاز به نیروهای متخصص
  3. استقرار مستقل میکروسرویس‌ها پیچیده‌است.
  4. میکروسرویس‌ها از نظر استفاده از شبکه پرهزینه هستند؛ زیرا نیاز به تعامل با یکدیگر دارند و همه این تماس‌های راه دور منجر به تأخیر شبکه می‌شود.
  5. امنیت کمتر به دلیل ارتباط بین سرویس‌ها
  6. اشکال زدایی دشوار است

نظرات اشتراک‌ها
مثالی از کاربرد واژه‌ی dynamic جهت جایگزین کردن آن با DTOs
مطلب تکمیلی 
dynamic type 
Pros: This approach reduces the need to modify static ViewModel classes whenever you update the SQL sentence of a query, making this design approach pretty agile when coding, straightforward, and quick to evolve in regard to future changes.
Cons: In the long term, dynamic types can negatively impact the clarity and the compatibility of a service with client apps. In addition, middleware software like Swashbuckle cannot provide the same level of documentation on returned types if using dynamic types. 

ViewModel (DTO) 
Pros : Having static predefined ViewModel classes, like “contracts” based on explicit DTO classes, is definitely better for public APIs but also for long term microservices, even if they are only used by the same application.
If you want to specify response types for Swagger, you need to use explicit DTO classes as the return type. Therefore, predefined DTO classes allow you to offer richer information from Swagger. That improves the API documentation and compatibility when consuming an API.
Cons : As mentioned earlier, when updating the code, it takes some more steps to update the DTO classes.  
مطالب
آشنایی با Window Function ها در SQL Server بخش اول
Window Function‌ها برای اولین بار در نسخه SQL Server 2005 ارائه گردیدند، و در ورژن‌های جدیدتر SQL Server، به تعداد این فانکشنها افزوده شده است.

تعریف Window Function :
        معمولا از این نوع فانکشنها روی مجموعه ای از ROW‌های یک جدول، در جهت اعمال عملیاتهای محاسباتی ،ارزیابی داده ها، رتبه بندی و غیرو... استفاده می‌گردد، به بیان ساده‌تر بوسیله Window Function‌ها می‌توان، ROW‌های یک جدول را گروه بندی نمود. و روی گروه‌ها از توابع جمعی (Aggregate Functions ) استفاده کرد. این نوع فانکشنها از قابلیت و انعطاف پذیری زیادی برخوردار می‌باشند، و بوسیله آنها می‌توان نتایج (خروجی) بسیار مفیدی از Query ها، بدست آورد، معمولا از این نوع فانکشنها در            Data Mining (داده کاوی) و گزارشگیری‌ها استفاده می‌گردد. و آگاهی و روش استفاده از Window Function‌ها برای برنامه نویسان و DBA ها، می‌تواند بسیار مفید باشد.
مفهوم Window Function مطابق استاندارد ISO و ANSI می‌باشد، و دیتابیس هایی همچون Oracle،DB2،Sybase از آن پشتیبانی می‌نمایند.برای اطلاعات بیشتر می‌توانید به سایت‌های زیر مراجعه کنید:
کلمه "Window" در  Window Function، به مجموعه ROW هایی اشاره می‌کند، که محاسبات و ارزیابی و غیرو... روی آنها اعمال می‌گردد. 
Window Function‌ها برای ارائه قابلیت‌های خود، از Over Clause استفاده می‌کنند. اگر مقاله آشنایی با Row_Number،Rank،Dense_Rank،NTILE را مطالعه کرده باشید، می‌توان هریک از آنها را یک Window Function دانست.
برای شروع، به بررسی Over Clause می‌پردازیم، و Syntax آن به شرح ذیل می‌باشد:
OVER ( 
       [ <PARTITION BY clause> ]
       [ <ORDER BY clause> ] 
       [ <ROW or RANGE clause> ]
      )

<PARTITION BY clause> ::=
PARTITION BY value_expression , ... [ n ]

<ORDER BY clause> ::=
ORDER BY order_by_expression
    [ COLLATE collation_name ] 
    [ ASC | DESC ] 
    [ ,...n ]

<ROW or RANGE clause> ::=
{ ROWS | RANGE } <window frame extent>

<window frame extent> ::= 
{   <window frame preceding>
  | <window frame between>
}

<window frame between> ::= 
  BETWEEN <window frame bound> AND <window frame bound>

<window frame bound> ::= 
{   <window frame preceding>
  | <window frame following>
}

<window frame preceding> ::= 
{
    UNBOUNDED PRECEDING
  | <unsigned_value_specification> PRECEDING
  | CURRENT ROW
}

<window frame following> ::= 
{
    UNBOUNDED FOLLOWING
  | <unsigned_value_specification> FOLLOWING
  | CURRENT ROW
}

<unsigned value specification> ::= 
{  <unsigned integer literal> }
OVER دارای سه آرگومان اختیاری است که هر کدام را به تفصیل بررسی می‌کنیم:
1- PARTITION BY clause : بوسیله این پارامتر می‌توانیم Row‌های یک جدول را گروه بندی نماییم. این پارامتر یک  value_expression می پذیرد. یک Value_expression می‌تواند نام یک ستون ، یک Scalar Subquery ، Scalar Function و غیرو باشد.
2- ORDER BY clause : از نامش مشخص است و برای Sort استفاده می‌شود، و ویژگی‌های Order By در آن اعمال می‌گردد. به جز Offset.
3- ROW or RANGE clause :این پارامتر بیشتر برای محدود نمودن Row در یک Partition (گروه) مورد استفاده قرار می‌گیرد، به عنوان مثال نقطه شروع و پایان را می‌توان بوسیله پارامتر فوق تعیین نمود.
Row و Range نسبت به هم یک تفاوت عمده دارند،و آن این است که، اگر از ROW Clause استفاده نمایید، ارتباط ROW‌های قبلی یا بعدی، نسبت به Row جاری،بصورت فیزیکی (physical association ) سنجیده می‌شود، بطوریکه با استفاده از Range Clause ارتباط سطرهای قبلی و بعدی، نسبت به سطر جاری بصورت منطقی (logical association ) در نظر گرفته می‌شود. ممکن است درک این مطلب کمی سخت باشد، در ادامه با مثالهایی که بررسی می‌نماییم، براحتی تفاوت این دو را متوجه می‌شوید.
Row یا Range در قالب‌های متفاوتی مقدار می‌پذیرند، که هر کدام را بررسی می‌کنیم:
UNBOUNDED PRECEDING : بیانگر اولین سطر Partition می‌باشد. UNBOUNDED PRECEDING  فقط نقطه شروع را مشخص می‌نماید.
UNBOUNDED FOLLOWING : بیانگر آخرین سطر Partition می‌باشد. UNBOUNDED FOLLOWING فقط نقطه پایانی را مشخص می‌نماید.
CURRENT ROW : اولین سطر جاری یا آخرین سطر جاری را مشخص می‌نماید.
n PRECEDING یا unsigned value specification> PRECEDING> : تعداد سطر‌های قبل از سطر جاری را تعیین می‌کند، n یا <unsigned value specification>تعداد سطر‌های قبل از سطر جاری را تعیین می‌نماید. از n PRECEDING نمی توان برای Range استفاده نمود.  
n FOLLOWING یا unsigned value specification> FOLLOWING> : تعداد سطرهای بعد از سطر جاری را تعیین می‌کند، n یا<unsigned value specification> تعداد سطر  های بعد از سطر جاری را تعیین می‌نماید. از n FOLLOWING نمی توان برای Range استفاده نمود.
<BETWEEN <window frame bound > AND <window frame bound  : از چارچوب فوق برای Range و Row می‌توان استفاده نمود، و نقطه آغازین و نقطه پایانی توسط قالب فوق تعیین می‌گردد. نکته قابل توجه آن است که نقطه پایانی نمی‌تواند، کوچکتر از نقطه آغازین گردد.
در ادامه برای درک هرچه بیشتر تعاریف بیان شده، چندین مثال می‌زنیم و هر کدام را بررسی می‌نماییم:
در ابتدا Script زیر را اجرا نمایید، که شامل جدولی به نام Revenue (سود،درآمد) و درج چند درکورد در آن:
CREATE TABLE REVENUE
(
[DepartmentID] int,
[Revenue] int,
[Year] int
);
 
insert into REVENUE
values (1,10030,1998),(2,20000,1998),(3,40000,1998),
 (1,20000,1999),(2,60000,1999),(3,50000,1999),
 (1,40000,2000),(2,40000,2000),(3,60000,2000),
 (1,30000,2001),(2,30000,2001),(3,70000,2001)
 
مثال اول : می‌خواهیم براساس فیلد DepartmentID جدول Revenue را Partition بندی نماییم و از توابع جمعی AVG و SUM روی فیلد درآمد(Revenue) استفاده کنیم.
ابتدا Script زیر را اجرا می‌کنیم:
 select *,
 avg(Revenue) OVER (PARTITION by DepartmentID) as AverageRevenue,
 sum(Revenue) OVER (PARTITION by DepartmentID) as TotalRevenue
from REVENUE
order by departmentID, year;
خروجی بصورت زیر خواهد بود:

        مطابق شکل، جدول براساس  فیلد DepartmentID به سه Partition تقسیم شده است، و عملیات میانگین و جمع روی فیلد Revenue انجام شده است و عملیات Sort روی هرگروه بطور مستقل انجام گرفته است. چنین کاری را نمی‌توانستیم بوسیله Group By انجام دهیم.
مثال دوم : نحوه استفاده از ROWS PRECEDING،در این مثال قصد داریم عملیات جمع را روی فیلدRevenue انجام دهیم. بطوریکه جمع هر مقدار برابر است با سه مقدار قبلی + مقدار جاری:
 لطفا رکورد‌های زیر را به جدول فوق درج نمایید:
 insert into REVENUE
 values(1,90000,2002),(2,20000,2002),(3,80000,2002),
 (1,10300,2003),(2,1000,2003), (3,90000,2003),
 (1,10000,2004),(2,10000,2004),(3,10000,2004),
 (1,20000,2005),(2,20000,2005),(3,20000,2005),
 (1,40000,2006),(2,30000,2006),(3,30000,2006),
 (1,70000,2007),(2,40000,2007),(3,40000,2007),
 (1,50000,2008),(2,50000,2008),(3,50000,2008),
 (1,20000,2009),(2,60000,2009),(3,60000,2009),
 (1,30000,2010),(2,70000,2010),(3,70000,2010),
 (1,80000,2011),(2,80000,2011),(3,80000,2011),
 (1,10000,2012),(2,90000,2012),(3,90000,2012)
سپس Script زیر را اجرا می‌نماییم:
select Year, DepartmentID, Revenue,
sum(Revenue) OVER (PARTITION by DepartmentID ORDER BY [YEAR]
             ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) as Prev3
From REVENUE order by departmentID, year;
خروجی :

        در Script بالا، جدول را براساس فیلد DepartmentID گروه بندی می‌کنیم، که سه گروه ایجاد می‌شود، هر گروه را بطور مستقل، روی فیلد Year بصورت صعودی مرتب می‌نماییم. حال برای آنکه بتوانیم سیاست جمع، روی فیلد Revenue، را پیاده سازی نماییم ، قطعه کد زیر را در Script بالا اضافه کردیم.
ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) as Prev3
     برای شرح چگونگی استفاده از PRECEDING،فقط به شرح گروه اول بسنده می‌کنیم. مقدار جمع فیلد Revenue سطر اول، که قبل از آن سطری وجود ندارد، برابر است با  مقدار خود، یعنی 10030، مقدار جمع فیلد Revenue سطر دوم برابر است با حاصل جمع مقدار فیلدRevenue سطر اول و دوم ، یعنی 30030 . این روند تا سطر چهار ادامه دارد، اما برای بدست آوردن مقدار جمع فیلدRevenue سطر پنجم، مقدار جمع فیلد Revenue سطر دوم،سوم،چهارم و پنجم در نظر گرفته می‌شود، و مقدار فیلدRevenue سطر اول در حاصل جمع در نظر گرفته نمی‌شود،بنابراین مقدار جمع فیلد Revenue سطر پنجم برابر است با 180000. در صورت مسئله گفته بودیم، مقدار جمع فیلد Revenue هر سطر جاری برابر است با حاصل جمع مقدارسطر جاری و مقادیر سه سطر ماقبل خود.

مثال سوم: نحوه استفاده از  ROWS FOLLOWING، این مثال عکس مثال دوم است، یعنی حاصل جمع مقدار فیلد Revenue هر سطر برابر است با حاصل جمع سطر جاری با سه سطر بعد از خود. بنابراین Script زیر را اجرا نمایید:
select Year, DepartmentID, Revenue,
 sum(Revenue) OVER (PARTITION by DepartmentID ORDER BY [YEAR]
              ROWS BETWEEN CURRENT ROW AND 3 FOLLOWING) as Next3
From REVENUE order by departmentID, year;
خروجی :

مطابق شکل مقدار جمع فیلد اول برابراست با حاصل جمع مقدار سطر جاری و سه سطر بعد از آن.
نکته ای که در مثالهای دوم و سوم،می بایست به آن توجه نمود، این است که در زمان استفاده از Row یا Range ، استفاده از Order by در Partition الزامی است، در غیر این صورت با خطا مواجه می‌شوید.


نحوه استفاده از UNBOUNDED PRECEDING ، این امکان در T-SQL Server 2012 افزوده شده است. 
مثال چهار: در این مثال می‌خواهیم کمترین سود بدست آمده در چند سال را بدست آوریم:
ابتدا Script زیر را اجرا نمایید:
select Year, DepartmentID, Revenue,
       min(Revenue) OVER (PARTITION by DepartmentID ORDER BY [YEAR]
                    ROWS UNBOUNDED PRECEDING) as MinRevenueToDate
From REVENUE order by departmentID, year;
خروجی:

طبق تعریف UNBOUNDED PRECEDING اولین سطر هر Partition را مشخص می‌نماید، و چون از PRECEDING استفاده کرده ایم، بنابراین مقایسه همیشه بین سطر جاری و  سطر‌های قبل از آن انجام می‌پذیرد. بنابراین خواهیم داشت، کمترین مقدار فیلد Revenue در سطر اول، برابر با مقدار خود می‌باشد، چون هیچ سطری ماقبل از آن وجود ندارد. در سطر دوم مقایسه کمترین مقدار، بین 20000 و 10030 انجام می‌گیرد، که برابر است با 10030، در سطر سوم، مقایسه بین مقادیر سطر اول،دوم و سطر سوم صورت می‌گیرد، یعنی کمترین مقدار بین 40000،20000 و 10030، بنابراین کمترین مقدار سطر سوم برابر است با 10030. 
به بیان ساده‌تر برای بدست آوردن کمترین مقدار هر سطر، مقدار سطر جاری با مقادیر همه سطرهای ماقبل خود مقایسه می‌گردد.
برای بدست آوردن کمترین مقدار در سطر ششم، مقایسه بین مقادیر سطر‌های اول،دوم،سوم،چهارم،پنجم و ششم صورت می‌گیرد که عدد 10000 بدست می‌آید و الی آخر...
نکنه: اگر در Over Clause شرط Order by را اعمال نماییم، اما از Row یا Range استفاده نکنیم، SQL Server بصورت پیش فرض از قالب زیر استفاده می‌نماید:
RANGE UNBOUNDED PRECEDING AND CURRENT ROW 
برای روشن‌تر شدن مطلب فوق مثالی می‌زنیم:
ابتدا Script زیر را اجرا نمایید، که شامل ایجاد یک جدول و درج چند رکورد در آن می‌باشد:
CREATE TABLE Employees (  
    EmployeeId INT IDENTITY PRIMARY KEY,  
    Name VARCHAR(50),  
    HireDate DATE NOT NULL,  
    Salary INT NOT NULL  
)  
GO  
INSERT INTO Employees (Name, HireDate, Salary)  
VALUES   
    ('Alice', '2011-01-01', 20000),  
    ('Brent', '2011-01-15', 19000),  
    ('Carlos', '2011-02-01', 22000),  
    ('Donna', '2011-03-01', 25000),  
    ('Evan', '2011-04-01', 18500)  
GO  
سپس Script زیر را اجرا نمایید:
SELECT  
    Name,   
    Salary,   
    AVG(Salary) OVER(ORDER BY HireDate) AS avgSalary  
FROM Employees  
GO 
خروجی :

حال اگر Script زیر را نیز اجرا نمایید، خروجی آن مطابق شکل بالا خواهد بود:
SELECT  
    Name,   
    Salary,   
    AVG(Salary) OVER(ORDER BY HireDate 
                 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS avgSalary  
FROM Employees  
GO
توضیح درباره Script بالا، در این روش برای بدست آوردن میانگین هر سطر، مقدار سطر جاری با مقادیر سطر‌های ماقبل خود جمع و تقسیم بر تعداد سطر می‌شود.
سطر دوم 20000 + 19000 تقسیم بر دو برابر است با 19500
میانگین سطر پنجم، حاصل جمع فیلد Salary همه مقادیر سطرها تقسیم بر 5 
*** اگر بخواهید بوسیله Over Clause ، میانگین همه سطر‌ها یکسان باشد می‌توانید از Script زیر استفاده نمایید:
SELECT  
    Name,   
    Salary,   
    AVG(Salary) OVER(ORDER BY HireDate   
                        RANGE   
                        BETWEEN UNBOUNDED PRECEDING   
                        AND UNBOUNDED FOLLOWING  
                    ) AS avgSalary  
FROM Employees  
GO  
خروجی :

منظور از  ROWS BETWEEN  UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING  یعنی در محاسبه میانگین برای هر سطر تمامی مقادیر سطر‌های دیگر در نظر گرفته شود.
پایان بخش اول
امیدوارم مفید واقع شده باشد.