public interface IUnitOfWork { void Dispose();
DbSet<T> Set<T>() where T : class; int SaveChanges(); Database Database { get; } }
در یک طبقه بندی کلی، عملگرهای پرس و جو بر اساس ورودی و خروجی آنها به سه دسته تقسیم میشوند:
1- نتیجهی توالی ورودی، بصورت یک توالی، به خروجی ارسال میشود.
2- نتیجهی توالی ورودی، بصورت یک عنصر یکتا و واحد به خروجی ارسال میشود.
3- اثری از ورودی در توالی خروجی وجود ندارد (این عملگرها عناصر خودشان را تولید میکنند).
دستهی آخر شاید کمی عجیب به نطر برسد. این عملگرها هیچ توالی ورودی را دریافت نمیکنند. مثلا میتوان از طریق این عملگرها، یک توالی از اعداد صحیح را تولید کرد.
تقسیم بندی عملگرهای پرس و جو بر اساس عملکرد به صورت زیر میباشد :
- محدود کننده (Restriction)
where
- بازتابی (Projection)
Select,SelectMany
- جداکننده (Partitioning)
Take,Skip,TakeWhile,SkipWhile
- مرتب سازی (Ordering)
OrderBy,OrderByDescending,ThenBy,ThenByDescending,Reverse
- گروه بندی (Grouping)
GroupBy
- مجموعه (Set)
Concat,Union,Intersect,Except
- تبدیل (Conversion)
ToArray,ToList,ToDictionary,ToLookup,OfType,Cast
- عنصر(Element)
First,FirstOrDefault,Last,LastOrDefalt,Single,SingleOrDefault
- عنصر در (ElementAt)
ElementAtOrDefault,DefaultIfEmpty
- تولید (Generation)
Empty,Range,Report
- کمی (Quantifier)
Any,All,Contains,SequenceEqual
- مجموعه (Aggregate)
Count,LongCount,Sum,Min,Max,Average,Aggregate
- اتصال (Join)
Join,GroupJoin,Zip
در این مطلب عملگرهای محدود کننده، بازتابی و جداکننده، بررسی خواهند شد. بعد از معرفی هر عملگر، معادل عبارتهای پرس و جوی آنها نیز معرفی خواهند شد.
این عملگر، عناصری را به خروجی ارسال میکند که با گزارهی (Predicate) تعریف شده مطابقت داشته باشند.
نکته : گزاره (Predicate) تابعی است که اگر شرط آن تامین شود، مقدار true و در غیر اینصورت مقدار false را باز میگرداند.
مثال :
Ingredient[] ingredients = { new Ingredient{Name = "Sugar", Calories=500}, new Ingredient{Name = "Egg", Calories=100}, new Ingredient{Name = "Milk", Calories=150}, new Ingredient{Name = "Flour", Calories=50}, new Ingredient{Name = "Butter", Calories=200}, }; IEnumerable<Ingredient> query = ingredients.Where(x => x.Calories >= 200); foreach (var ingredient in query) { Console.WriteLine(ingredient.Name); }
خروجی کد بالا:
Sugar Butter
IEnumerable<Ingredient> query = ingredients.Where((ingredient, index) => ingredient.Name == "Sugar" || index == 4);
پیاده سازی توسط عبارتهای پرس و جو
در روش عبارتهای پرس و جو، کلمهی کلیدی where بههمراه یک عبارت منطقی در پرس و جو ظاهر میشود:
IEnumerable<Ingredient> gueryExpression = from i in ingredients where i.Calories >= 200 select i;
عملگرهای بازتاب (Projection Operators)
عملگرهای پرس و جوی بازتابی، یک توالی ورودی را دریافت و با تبدیل عناصر آنها، یک توالی خروجی را تولید میکنند.
Select
عملگر پرس و جوی select هر عنصر توالی ورودی را به یک عنصر در توالی خروجی تبدیل میکند. تعداد عناصر ورودی و خروجی در این حالت یکسان میباشند.
پرس و جوی زیر عناصر توالی ورودی Ingredient را به عناصر رشتهای در توالی خروجی بازتاب میکند. عبارت Lambda تعریف شده، نحوهی بازتاب عناصر را مشخص میکند (هر عنصر ingredient به یک عنصر رشتهای بازتاب میشود):
IEnumerable<string> query = ingredients.Select(x => x.Name);
IEnumerable<int> query = ingredients.Select(x => x.Name.Length);
در عملیات بازتاب میتوان یک شیء جدید را در توالی خروجی ایجاد کرد. در کد زیر عناصر Ingredient به یک عنصر جدید از نوع IngredientNameAndLenght بازتاب شده است.
class IngredientNameAndLength { public string Name { get; set; } public int Length { get; set; } public override string ToString() { return Name + " " + Length; } } IEnumerable<IngredientNameAndLength> query = ingredients.Select(x => new IngredientNameAndLength { Name = x.Name, Length = x.Name.Length });
var query = ingredients.Select(x => new { Name = x.Name, Length = x.Name.Length });
{ Name = Sugar, Length = 5 } { Name = Egg, Length = 3 } { Name = Milk, Length = 4 } { Name = Flour, Length = 5 } { Name = Butter, Length = 6 }
پیاده سازی توسط عبارتهای پرس و جو
کلمهی کلیدی select در عبارتهای پرس و جو، به شکل زیر استفاده میشود:
var query = from i in ingredients select new { Name=i.Name, Length=i.Name.Length };
برعکس دستور select که به ازای هر عنصر در توالی ورودی، یک عنصر را در توالی خروجی بازتاب میکرد، دستور SelectMany ممکن است تعداد عناصر کمتر و یا بیشتری را در توالی خروجی بازتاب کند (انتخاب مقادیر یک مجموعه از مجموعهی دیگر).
عبارت Lambda نوشته شده در عملگر Select، یک مقدار را باز میگرداند. اما عبارت Lambda نوشته شده در عملگر SelectMany، یک توالی فرزند (Child Sequence) را ایجاد میکند. توالی فرزند ممکن است حاوی تعداد مختلفی از عناصر به ازای هر عنصر در توالی ورودی باشد.
در مثال زیر عبارت Lambda یک توالی فرزند از کاراکترها ایجاد میکند (یک کاراکتر به ازای هر حرف از هر عنصر توالی ورودی). بهطور مثال عنصر ورودی Sugar، پس از پردازش توسط عبارت Lambda، یک توالی فرزند با 5 عنصر 's','u','g','e','r' فراهم میکند. هر رشتهی در توالی Ingredient میتواند تعداد حروف متفاوتی داشته باشد. در نتیجه عبارت Lambda، توالیهای فرزندی با طولهای مختلف ایجاد میکند.
مثال:
string[] ingredients = {"Sugar","Egg","Milk","Flour","Butter"}; IEnumerable<char> query = ingredients.SelectMany(x => x.ToCharArray()); foreach (var item in query) { Console.WriteLine(item); }
S u g a r E g g M i l k F l o u r B u t t e r
پیاده سازی توسط عبارتهای پرس و جو
در روش عبارتهای پرس و جو یک عبارت (clause) اضافی from برای تولید یک توالی فرزند به کار برده میشود. خروجی کد زیر مشابه کد قبلی است:
string[] ingredients = {"Sugar","Egg","Milk","Flour","Butter"}; IEnumerable<char> query2 = from i in ingredients from c in i.ToCharArray() select c; foreach (var item in query2) { Console.WriteLine(item); }
عملگرهای جداکننده، یک توالی ورودی را دریافت و آنها را از هم جدا میکنند.
Take
عملگر Takeیک توالی ورودی را دریافت کرده و تعداد مشخصی از توالی را باز میگرداند.
مثال: عملگر Take، سه عضو اول توالی Ingredient را باز میگرداند:
Ingredient[] ingredients = { new Ingredient{Name = "Sugar", Calories=500}, new Ingredient{Name = "Egg", Calories=100}, new Ingredient{Name = "Milk", Calories=150}, new Ingredient{Name = "Flour", Calories=50}, new Ingredient{Name = "Butter", Calories=200}, }; IEnumerable<Ingredient> query = ingredients.Take(3); foreach (var ingredient in query) { Console.WriteLine(ingredient.Name); }
Sugar Egg Milk
Ingredient[] ingredients = { new Ingredient{Name = "Sugar", Calories=500}, new Ingredient{Name = "Egg", Calories=100}, new Ingredient{Name = "Milk", Calories=150}, new Ingredient{Name = "Flour", Calories=50}, new Ingredient{Name = "Butter", Calories=200}, }; IEnumerable<Ingredient> query = ingredients.Where(x=>x.Calories>100).Take(2); foreach (var ingredient in query) { Console.WriteLine(ingredient.Name); }
Sugar Milk
پیاده سازی توسط عبارتهای پرس و جو
کلمهی کلیدی (Key word) جایگزینی برای عملگر Take وجود ندارد، ولی میتوان با ترکیب دو روش نوشتن پرس و جو، خروجی مورد نظر را تولید کرد:
IEnumerable<Ingredient> query = (from i in ingredients where i.Calories > 100 select i).Take(2); TakeWhile
کد زیر تا زمانی که خصوصیت Calorie توالی ورودی بزرگتر و مساوی 100 باشد، عناصر را جدا میکند.
Ingredient[] ingredients = { new Ingredient{Name = "Sugar", Calories=500}, new Ingredient{Name = "Egg", Calories=100}, new Ingredient{Name = "Milk", Calories=150}, new Ingredient{Name = "Flour", Calories=50}, new Ingredient{Name = "Butter", Calories=200}, }; IEnumerable<Ingredient> query = ingredients.TakeWhile(x => x.Calories >= 100); foreach (var ingredient in query) { Console.WriteLine(ingredient.Name); }
Sugar Egg Milk
پیاده سازی توسط عبارتهای پرس و جو
برای این عملگر هم کلمهی کلیدی (Key word) جایگزینی وجود ندارد و با ترکیب دو روش نوشتن پرس و جو نتیجهی دلخواه حاصل میشود.
Skip
این عملگر تعداد مشخصی از عناصر را از ابتدای توالی نادیده گرفته و باقی عناصر را باز میگرداند.
کد زیر سه عضو اول توالی را نادیده گرفته و مابقی را باز میگرداند:
Ingredient[] ingredients = { new Ingredient{Name = "Sugar", Calories=500}, new Ingredient{Name = "Egg", Calories=100}, new Ingredient{Name = "Milk", Calories=150}, new Ingredient{Name = "Flour", Calories=50}, new Ingredient{Name = "Butter", Calories=200}, }; IEnumerable<Ingredient> query = ingredients.Skip(3); foreach (var ingredient in query) { Console.WriteLine(ingredient.Name); }
Flour Butter
پیاده سازی توسط عبارتهای پرس و جو
برای این عملگر هم کلمهی کلیدی (Key word) جایگزینی وجود ندارد و با ترکیب دو روش نوشتن پرس و جو، نتیجهی دلخواه حاصل میشود.
با ترکیب عملگر Take و Skip میتوان اطلاعات را بهصورت صفحه بندی به کاربر ارائه کرد. مثال زیر این حالت را نشان میدهد.
IEnumerable<Ingredient> firstPage = ingredients.Take(2); IEnumerable<Ingredient> secondPage = ingredients.Skip(2).Take(2); IEnumerable<Ingredient> thirdPage = ingredients.Skip(4).Take(2); Console.WriteLine("First Page : "); foreach (var ingredient in firstPage) { Console.WriteLine(" - " + ingredient.Name); } Console.WriteLine("Second Page : "); foreach (var ingredient in secondPage) { Console.WriteLine(" - " + ingredient.Name); } Console.WriteLine("Third Page : "); foreach (var ingredient in thirdPage) { Console.WriteLine(" - " + ingredient.Name); }
First Page : - Sugar - Egg Second Page : - Milk - Flour Third Page : - Butter SkipWhile
مثال:
Ingredient[] ingredients = { new Ingredient{Name = "Sugar", Calories=500}, new Ingredient{Name = "Egg", Calories=100}, new Ingredient{Name = "Milk", Calories=150}, new Ingredient{Name = "Flour", Calories=50}, new Ingredient{Name = "Butter", Calories=200}, }; IEnumerable<Ingredient> query = ingredients.SkipWhile(x => x.Name != "Milk"); foreach (var ingredient in query) { Console.WriteLine(ingredient.Name); }
Milk Flour Butter
دوره 8 ساعته Microservices در دات نت
Introduction to .NET Microservices (.NET 8)
In this Introduction course, we will learn Microservices with .NET 8 (MVC).
Microservices is an upcoming technology, where it is very easy to scale and break down large project in simple and manageable services.
In this course we will build multiple services and see how they function together by communicating in synchronous and asynchronous manner.
⭐️ Course Contents ⭐️
⌨️ (0:00:01) Section 1 - Welcome & Getting Started
⌨️ (0:28:15) Section 2 - Coupon API - Fundamentals
⌨️ (1:15:54) Section 3 - Coupon API - CRUD
⌨️ (2:21:24) Section 4 - Auth API
⌨️ (3:20:08) Section 5 - Consuming Auth API
⌨️ (4:26:53) Section 6 - Product API
⌨️ (4:57:59) Section 7 - Home and Details Page
⌨️ (5:09:35) Section 8 - Shopping Cart
⌨️ (6:08:04) Section 9 - Shopping Cart in Web Project
⌨️ (6:58:06) Section 10 - Service Bus
⌨️ (7:23:42) Section 11 - Email API - Service Bus
⌨️ (7:54:11) What's Next?
مروری بر کاربردهای Action و Func - قسمت دوم
public static T CacheRead<T>(this HttpContextBase httpContext, string key, int durationMinutes, Func<T> ifNullRetrievalMethod) { var item = httpContext.Cache[key]; if (item == null) { item = ifNullRetrievalMethod(); if (item == null) return default(T); CacheInsert(httpContext, key, item, durationMinutes); } return (T)item; }
تعریف نوع جنریک به صورت متغیر
در این آدرس کد رو قرار دادم : http://pastebin.com/Q4bu1VV1
ولی از این خط 14 ارور میگیرم. در کل میخواستم بدونم چطور T رو به هر کلاسی Cast کنم. ممنون
از مطلب مفیدی که تهیه کردید ممنون.
میشود از طریق خاصیت Brush که فعلا فقط خواندنی هست، طرحهای مختلفی برای پس زمینه اشیاع ایجاد کرد. مانند Paint.net و یا MS Paint.
اگر به صورت زیر تعریف کنیم فکر میکنم کمی کاملتر باشه!
private Brush _backgroundBrush; /// <summary> /// Gets or sets the brush. /// </summary> /// <value> /// The brush. /// </value> public Brush BackgroundBrush { get { return _backgroundBrush; } private set { _backgroundBrush = (value != null) ? value : new SolidBrush(BackgroundColor); } } //-------------------------------------[Methode for set brush]-------------------------------------- public virtual void SetBackgroundBrushAsHatch(HatchStyle hatchStyle) { HatchBrush brush = new HatchBrush(hatchStyle, BackgroundColor); BackgroundBrush = brush; } public virtual void SetBackgroundBrushAsSolid() { SolidBrush brush = new SolidBrush(BackgroundColor); BackgroundBrush = brush; } public virtual void SetBackgroundBrushAsLinearGradient() { LinearGradientBrush brush = new LinearGradientBrush(StartPoint, EndPoint, ForeColor, BackgroundColor); BackgroundBrush = brush; }
که اگر بخواهیم میتونیم باز بیشتر Customize بکنیمشون.
مقدمه
Profiler یک ابزار گرافیکی برای ردیابی و نظارت بر کارآئی SQL Server است. امکان ردیابی اطلاعاتی در خصوص رویدادهای مختلف و ثبت این دادهها در یک فایل (با پسوند trc) یا جدول برای تحلیلهای آتی نیز وجود دارد. برای اجرای این ابزار مراحل زیر را انجام دهید:1- اصطلاحات
1-1- رویداد (Event):
یک رویداد، کاری است که توسط موتور بانک اطلاعاتی (Database Engine) انجام میشود. برای مثال هر یک از موارد زیر یک رویداد هستند.- متصل شدن کاربران (login connections) قطع شدن ارتباط یک login
- اجرای دستورات T-SQL، شروع و پایان اجرای یک رویه، شروع و پایان یک دستور در طول اجرای یک رویه، اجرای رویههای دور Remote Procedure Call
- باز شدن یک Cursor
- بررسی و کنترل مجوزهای امنیتی
1-2- کلاس رویداد (Event Class):
برای بکارگیری رویدادها در Profiler، از یک Event Class استفاده میکنیم. یک Event Class رویدادی است که قابلیت ردیابی دارد. برای مثال بررسی ورود و اتصال کاربران با استفاده از کلاس Audit Login قابل پیاده سازی است. هر یک از موارد زیر یک Event Class هستند.- SQL:BatchCompleted
- Audit Login
- Audit Logout
- Lock: Acquired
- Lock: Released
1-3- گروه رویداد (Event Category):
یک گروه رویداد شامل رویدادهایی است که به صورت مفهومی دسته بندی شده اند. برای مثال، کلیه رویدادهای مربوط به قفلها از جمله Lock: Acquired (بدست آوردن قفل) و Lock: Released (رها کردن قفل) در گروه رویداد Locks قرار دارند.1-4- ستون داده ای (Data Column):
یک ستون داده ای، خصوصیت و جزئیات یک رویداد را شامل میشود. برای مثال در یک Trace که رویدادهای Lock: Acquired را نظارت میکند، ستون Binary Data شامل شناسه (ID) یک صفحه و یا یک سطر قفل شده است و یا اینکه ستون Duration مدت زمان اجرای یک رویه را نمایش میدهد.1-5- الگو (Template):
یک الگو، مشخص کننده تنظیمات پیش گزیده برای یک Trace است، این تنظیمات شامل رویدادهایی است که نیاز دارید بر آنها نظارت داشته باشید. هنگامیکه یک Trace براساس یک الگو اجرا شود، رویدادهای مشخص شده، نظارت میشوند و نتیجه به صورت یک فایل یا جدول قابل مشاهده خواهد بود.1-6- ردیاب (Trace):
یک Trace دادهها را براساس رویدادهای انتخاب شده، جمع آوری میکند. امکان اجرای بلافاصله یک Trace برای جمع آوری اطلاعات با توجه به رویدادهای انتخاب شده و ذخیره کردن آن برای اجرای آتی وجود دارد.1-7- فیلتر (Filter):
هنگامی که یک Trace یا الگو ایجاد میشود، امکان تعریف شرایطی برای فیلتر کردن دادههای جمع آوری شده نیز وجود دارد. این کار باعث کاهش حجم دادههای گزارش شده میشود. برای مثال اطلاعات مربوط به یک کاربر خاص جمع آوری میشود و یا اینکه رشد یک بانک اطلاعاتی مشخص بررسی میشود.2- انتخاب الگو (Profiler Trace Templates)
از آنجائیکه اصولاً انتخاب Eventهای مناسب، کار سخت و تخصصی میباشد برای راحتی کار تعدادی Templateهای آماده وجود دارد، برای مثال TSQL_Duration تاکیدش روی مدت انجام کار است و یا SP_Counts در مواردی که بخواهیم رویههای ذخیره شده را بهینه کنیم استفاده میشود در جدول زیر به شرح هر یک پرداخته شده است:الگو | هدف |
Blank | ایجاد یک Trace کلی |
SP_Counts | ثبت اجرای هر رویه ذخیره شده برای تشخیص اینکه هر رویه چند بار اجرا شده است |
Standard | ثبت آمارهای کارائی برای هر رویه ذخیره شده و Queryهای عادی SQL که اجرا میشوند و عملیات ورود و خروج هر Login (پیش فرض) |
TSQL | ثبت یک لیست از همه رویههای ذخیره شده و Queryهای عادی SQL که اجرا میشوند ولی آمارهای کارائی را شامل نمیشود |
TSQL_Duration | ثبت مدت زمان اجرای هر رویه ذخیره شده و هر Query عادی SQL |
TSQL_Grouped | ثبت تمام loginها و logoutها در طول اجرای رویههای ذخیره شده و هر Query عادی SQL، شامل اطلاعاتی برای شناسائی برنامه و کاربری که درخواست را اجرا میکند |
TSQL_Locks | ثبت اطلاعات انسداد (blocking) و بن بست (deadlock) از قبیل blocked processes، deadlock chains، deadlock graphs,... . این الگو همچنین درخواستهای تمام رویههای ذخیره شده و تمامی دستورات هر رویه و هر Query عادی SQL را دریافت میکند |
TSQL_Replay | ثبت اجرای رویههای ذخیره شده و Queryهای SQL در یک SQL Instance و مهیا کردن امکان اجرای دوباره عملیات در سیستمی دیگر |
TSQL_SPs | ثبت کارائی برای Queryهای SQL، رویههای ذخیره شده و تمامی دستورات درون یک رویه ذخیره شده و نیز عملیات ورود و خروج هر Login |
Tuning | ثبت اطلاعات کارائی برای Queryهای عادی SQL و رویههای ذخیره شده و یا تمامی دستورات درون یک رویه ذخیره شده |
3- انتخاب رویداد (SQL Trace Event Groups)
رویدادها در 21 گروه رویداد دسته بندی میشوند که در جدول زیر لیست شده اند:گروه رویداد | هدف |
Broker | 13 رویداد برای واسطه سرویس (Service Broker) |
CLR | 1 رویداد برای بارگذاری اسمبلیهای CLR (Common Language Runtime) |
Cursors | 7 رویداد برای ایجاد، دستیابی و در اختیار گرفتن Cursor |
Database | 6 رویداد برای رشد/کاهش (grow/shrink) فایل های Data/Log همچنین تغییرات حالت انعکاس (Mirroring) |
Deprecation | 2 رویداد برای آگاه کردن وضعیت نابسامان درون یک SQL Instance |
Errors and Warnings | 16 رویداد برای خطاها، هشدارها و پیغامهای اطلاعاتی که ثبت شده است |
Full Text | 3 رویداد برای پیگیری یک شاخص متنی کامل |
Locks | 9 رویداد برای بدست آوردن، رها کردن قفل و بن بست (Deadlock) |
OLEDB | 5 رویداد برای درخواستهای توزیع شده و RPC (اجرای رویههای دور) |
Objects | 3 رویداد برای وقتی که یک شی ایجاد، تغییر یا حذف میشود |
Performance | 14 رویداد برای ثبت نقشه درخواستها (Query Plan) برای استفاده نقشه راهنما (Plan Guide) به منظور بهینه سازی کارائی درخواست ها، همچنین این گروه رویداد در خواستهای متنی کامل (full text) را ثبت میکند |
Progress Report | 10 رویداد برای ایجاد Online Index |
Query Notifications | 4 رویداد برای سرویس اطلاع رسان (Notification Service) |
Scans | 2 رویداد برای وقتی که یک جدول یا شاخص، پویش میشود |
Security Audit | 44 رویداد برای وقتی که مجوزی استفاده شود، جابجائی هویتی رخ دهد، تنظیمات امنیتی اشیائی تغییر کند،یک SQL Instance شروع و متوقف شود و یک Database جایگزین شود یا از آن پشتیبان گرفته شود |
Server | 3 رویداد برای Mount Tape، تغییر کردن حافظه سرور و بستن یک فایل Trace |
Sessions | 3 رویداد برای وقتی که Connectionها موجود هستند و یک Trace فعال میشود، همچنین یک Trigger و یک تابع دسته بندی(classification functions) مربوط به مدیریت منابع(resource governor) رخ دهد |
Stored Procedures | 12 رویداد برای اجرای یک رویه ذخیره شده و دستورات درون آن ، کامپایل مجدد و استفاده از حافظه نهانی (Cache) |
Transactions | 13 رویداد برای شروع، ذخیره ، تائید و لغو یک تراکنش |
TSQL | 9 رویداد برای اجرای Queryهای SQL و جستجوهای XQUERY (در دادههای XML) |
User Configurable | 10 رویداد که شما میتوانید پیکربندی کنید |
4- انتخاب ستونهای داده ای ( Data Columns)
اگرچه میتوان همهی 64 ستون داده ای ممکن را برای ردیابی انتخاب کرد ولیکن دادههای Trace شما زمانی مفید خواهند بود که اطلاعات ضروری را ثبت کرده باشید. برای مثال شماره ترتیب تراکنشها را، برای یک رویداد RPC:Completed میتوانید برگردانید، اما همه رویههای ذخیره شده مقادیر را تغییر نمیدهند بنابراین شماره ترتیب تراکنشها فضای بیهوده ای را مصرف میکند. بعلاوه همه ستونهای داده ای برای تمامی رویدادهای Trace معتبر نیستند. برای مثال Read ، Write ،CPU و Duration برای رویدادهای RPC:Starting و SQL:BatchStarting معتبر نیستند.ApplicationName، NTUserName، LoginName، ClientProcessID، SPID، HostName، LoginSID، NTDomainName و SessionLoginName ، مشخص میکنند چه کسی و از چه منشاء دستور را اجرا کرده است.
ستون SessionLoginName معمولاً نام Login ای که از آن برای متصل شدن به SQL Instance استفاده شده است را نشان میدهد. در حالیکه ستون LoginName نام کاربری را که دستور را اجرا میکند نشان میدهد (EXECUTE AS). ستون ApplicationName خالی است مگر اینکه در ConnectionString برنامه کاربردیمان این خصوصیت (Property) مقداردهی شده باشد. ستون StartTime و EndTime زمان سرحدی برای هر رویداد را ثبت میکند این ستونها بویژه در هنگامی که به عملیات Correlate نیاز دارید مفید هستند.
5- بررسی چند سناریو نمونه
• یافتن درخواست هائی (Queries) که بدترین کارایی را دارا هستند.
برای ردیابی درخواستهای ناکارا، از رویداد RPC:Completed از دسته Stored Procedure و رویداد SQL:BatchCompleted از دسته TSQL استفاده میشود.• نظارت بر کارایی رویه ها
برای ردیابی کارائی رویه ها، از رویدادهای SP:Starting، SP:Completed، SP:StmtCompleted و SP:StmtStaring از کلاس Stored Procedure و رویدادهای SQL:BatchStarting ، SQL:BatchCompleted از کلاس TSQL استفاده میشود.• نظارت بر اجرای دستورات T-SQL توسط هر کاربر
برای ردیابی دستوراتی که توسط یک کاربر خاص اجرا میشود، نیاز به ایجاد یک Trace برای نظارت بر رویدادهای کلاسهای Sessions، ExistingConnection و TSQL داریم همچنین لازم است نام کاربر در قسمت فیلتر و با استفاده از DBUserName مشخص شود.• اجرا دوباره ردیاب (Trace Replay)
این الگو معمولاً برای debugging استفاده میشود برای این منظور از الگوی Replay استفاده میشود. در ضمن امکان اجرای دوباره عملیات در سیستمی دیگر با استفاده از این الگو مهیا میشود.• ابزار Tuning Advisor (راهنمای تنظیم کارائی)
این ابزاری برای تحلیل کارائی یک یا چند بانک اطلاعاتی و تاثیر عملکرد آنها بر بار کاری (Workload) سرویس دهنده است. یک بار کاری مجموعه ای از دستورات T-SQL است که روی بانک اطلاعاتی اجرا میشود. بعد از تحلیل تاثیر بارکاری بر بانک اطلاعاتی، Tuning Advisor توصیه هائی برای اضافه کردن، حذف و یا تغییر طراحی فیزیکی ساختار بانک اطلاعاتی ارائه میدهد این تغییرات ساختاری شامل پیشنهاد برای تغییر ساختاری موارد Clustered Indexes، Nonclustered Indexes، Indexed View و Partitioning است.برای ایجاد بارکاری میتوان از یک ردیاب تهیه شده در SQL Profiler استفاده کرد برای این منظور از الگوی Tuning استفاده میشود و یا رویدادهای RPC:Completed، SQL:BatchCompleted و SP:StmtCompleted را ردیابی نمائید.
• ترکیب ابزارهای نظارتی (Correlating Performance and Monitoring Data)
یک Trace برای ثبت اطلاعاتی که در یک SQL Instance رخ میدهد، استفاده میشود. System Monitor برای ثبت شمارندههای کارائی(performance counters) استفاده میشود و همچنین از منابع سخت افزاری و اجزای دیگر که روی سرور اجرا میشوند، تصاویری فراهم میکند. توجه شود که در مورد Correlating یک فایل ردیاب (trace file) و یک Counter Log (ابزار Performance )، ستون داده ای StartTime و EndTime باید انتخاب شود، برای این کار از منوی File گزینه Import Performance Data انتخاب میشود.• جستجوی علت رخ دادن یک بن بست
برای ردیابی علت رخ دادن یک بن بست، از رویدادهای RPC:Starting، SQLBatchStarting از دسته Stored Procedure و رویدادهای Deadlock graph، Lock:Deadlock و Lock:Deadlock Chain از دسته Locks استفاده میشود. ( در صورتی که نیاز به یک ارائه گرافیکی دارید از Deadlock graph استفاده نمائید، خروجی مطابق تصویر زیر میشود).
5-1- ایجاد یک Trace
1- Profiler را اجرا کنید از منوی File گزینه New Trace را انتخاب کنید و به SQL Instance مورد نظرتان متصل شوید.2- مطابق تصویر زیر برای Trace یک نام و الگو و تنظیمات ذخیره سازی فایل را مشخص کنید.
3- بر روی قسمت Events Selection کلیک نمائید.
4- مطابق تصویر زیر رویدادها و کلاس رویدادها را انتخاب کنید، ستونهای TextData، NTUserName، LoginName، CPU،Reads،Writes، Duration، SPID، StartTime، EndTime، BinaryData، DataBaseName، ServerName و ObjectName را انتخاب کنید.
5- روی Column Filters کلیک کنید و مطابق تصویر زیر برای DatabaseName فیلتری تنظیم کنید.
6- روی Run کلیک کنید. تعدادی Query و رویه ذخیره شده مرتبط با پایگاه داده AdventureWorks اجرا کنید .
5-2- ایجاد یک Counter Log
برای ایجاد یک Counter Log مراحل زیر را انجام دهید:1- ابزار Performance را اجرا کنید (برای این کار عبارتPerfMon را در قسمت Run بنویسید).
2- در قسمت Counter Logs یک log ایجاد کنید.
3- روی Add Counters کلیک کرده و مطابق تصویر موارد زیر را انتخاب کنید.
Select counters from list | Performance Object |
Output Queue Length | Network Interface |
% Processor Time | Processor |
Processor Queue Length | System |
Buffer Manager:Page life expectancy | SQLServer |
4- روی Ok کلیک کنید تا Counter Log ذخیره شود سپس روی آن راست کلیک کرده و آنرا Start کنید.
5-3- ترکیب ابزارهای نظارتی (Correlating SQL Trace and System Monitor Data)
1- Profiler را اجرا کنید از منوی File گزینه Open و سپس Trace File را انتخاب کنید فایل trc را که در گام اول ایجاد کردید، باز نمائید.2- از منوی File گزینه Import Performance Data را انتخاب کنید و فایل counter log را که در مرحله قبل ایجاد کردید انتخاب کنید.
نکته: اطلاعات فایل trc را میتوان درون یک جدول وارد کرد، بدین ترتیب میتوان آنالیز بیشتری داشت به عنوان مثال دستورات زیر این عمل را انجام میدهند.
SELECT * INTO dbo.BaselineTrace FROM fn_trace_gettable(' c:\performance baseline.trc ', default);
مطلبی را در سایت رادیکال 2 در مورد نمایش تعداد خواننده یک فید دیدم که پیاده سازی آن با سی شارپ و xml serialization به صورت زیر است:
using System;
using System.Xml;
using System.Xml.Serialization;
namespace Test
{
/// <summary>
/// کلاسی جهت نمایش تعداد خواننده فید وبلاگ شما
/// <example>CFeedBurner data = new CFeedBurner { FeedID = "fhphjt61bueu08k93ehujpu234" };
/// MessageBox.Show(data.Circulation().ToString());</example>
/// </summary>
class CFeedBurner
{
/// <summary>
/// آی دی فید شما زمانیکه به فید برنر لاگین کردهاید در تایتل صفحه مربوطه
/// </summary>
public string FeedID { get; set; }
/// <summary>
/// نگاشت فید به یک کلاس
/// </summary>
/// <returns>کلاس متناظر با فید</returns>
/// <exception cref="Exception">لطفا شماره شناسایی فید را وارد کنید</exception>
rsp deserializeFromXML()
{
if (FeedID == null)
throw new Exception("لطفا شماره شناسایی فید را وارد کنید");
XmlSerializer deserializer =
new XmlSerializer(typeof(rsp));
using (XmlReader reader = XmlReader.Create(
string.Format("https://feedburner.google.com/api/awareness/1.0/GetFeedData?id={0}", FeedID)))
{
return (rsp)deserializer.Deserialize(reader);
}
}
/// <summary>
/// دریافت تعداد خواننده فید
/// </summary>
/// <returns>آمار فید</returns>
/// <exception cref="Exception">اطلاعات فید شما قابل دریافت نیست</exception>
public int Circulation()
{
rsp data = deserializeFromXML();
if (data == null || data.feed == null || data.feed.Length == 0)
throw new Exception("اطلاعات فید شما قابل دریافت نیست");
if (data.feed[0].entry == null || data.feed[0].entry.Length == 0)
throw new Exception("اطلاعات فید شما قابل پردازش نیست");
return int.Parse(data.feed[0].entry[0].circulation);
}
}
}
xsd.exe GetFeedData.xml
xsd.exe GetFeedData.xsd /c
بررسی اینترفیس ICommand در WPF
using System; using System.Windows.Input; namespace Common.Mvvm { public class DelegateCommand<T> : ICommand { readonly Func<T, bool> _canExecute; readonly Action<T> _executeAction; public DelegateCommand(Action<T> executeAction, Func<T, bool> canExecute = null) { if (executeAction == null) throw new ArgumentNullException("executeAction"); _executeAction = executeAction; _canExecute = canExecute; } public event EventHandler CanExecuteChanged { add { if (_canExecute != null) CommandManager.RequerySuggested += value; } remove { if (_canExecute != null) CommandManager.RequerySuggested -= value; } } public bool CanExecute(object parameter) { return _canExecute == null || _canExecute((T)parameter); } public void Execute(object parameter) { _executeAction((T)parameter); } } }
public DelegateCommand<object> DoCopyAllLines { set; get; }
DoCopyAllLines = new DelegateCommand<object>(CopyAllLines, info => true);
private void CopyAllLines(object data) { // ... }