Build a Complete Blog App with Blazor Server - Step-by-Step Tutorial from Scratch by Abhay Prince
You will learn about fundamentals of Blazor Server, Routing, Shared Reusable Components, Custom Authentication, EF Core Code First, Passing data from parent to child components and vice versa, Passing events from child to parent components, Forms validations and submissions, styling components, using javascript with blazor. third party components integration with blazor, blazor lifecycle events, authentication and authorization in blazor server, programtically navigating between component pages, multiple routes paths for single component page, dynamic routes and getting data from routes, authorized view and much more...
PowerShell For SQL Full Course
f you’re a SQL Data Pro, check out this demo-packed course to explore using PowerShell to manage SQL Server and Azure SQL Database. Hear about the background of PowerShell, and learn PowerShell basics, such as how to get help, use cmdlets, and load modules. Look at task automation and configuration, and learn how to provision, deploy, and manage SQL Server in Azure Virtual Machines and Azure SQL Database. Plus, see how to use the SQLPS module to administer SQL Server, both on-premises and in Azure Virtual Machines. Don’t miss this practical PowerShell training
چرا XML و چرا پشتیبانی توکار از آن در SQL Server
فیلدهای XML از سال 2005 به امکانات توکار SQL Server اضافه شدهاند و بسیاری از مزایای دنیای NoSQL را درون SQL Server رابطهای مهیا میسازند. برای مثال با تعریف یک فیلد به صورت XML، میتوان از هر ردیف به ردیفی دیگر، اطلاعات متفاوتی را ذخیره کرد؛ به این ترتیب امکان کار با یک فیلد که میتواند اطلاعات یک شیء را قبول کند و در حقیقت امکان تعریف اسکیمای پویا و متغیر را در کنار امکانات یک بانک اطلاعاتی رابطهای که از اسکیمای ثابت پشتیبانی میکند، میسر میشود.
همچنین SQL Server در این حالت قابلیتی را ارائه میدهد که در بسیاری از بانکهای اطلاعاتی NoSQL میسر نیست. در اینجا در صورت نیاز و لزوم میتوان اسکیمای کاملا مشخصی را به یک فیلد XML نیز انتساب داد؛ هر چند این مورد اختیاری است و میتوان یک un typed XML را نیز بکار برد. به علاوه امکانات کوئری گرفتن توکار از این اطلاعات را به کمک XPath ترکیب شده با T-SQL، نیز فراموش نکنید.
بنابراین اگر یکی از اهداف اصلی گرایش شما به سمت دنیای NoSQL، استفاده از امکان تعریف اطلاعاتی با اسکیمای متغیر و پویا است، فیلدهای نوع XML اس کیوال سرور را مدنظر داشته باشید.
یک مثال عملی: فناوری Azure Dev Fabric's Table Storage (نسخه Developer ویندوز Azure که روی ویندوزهای معمولی اجرا میشود؛ یک شبیه ساز خانگی) به کمک SQL Server و فیلدهای XML آن طراحی شده است.
چرا XML و چرا پشتیبانی توکار از آن در SQL Server
یک سند XML معمولا بیشتر از یک قطعه داده را در خود نگهداری میکند و نوع دادهی پیچیده محسوب میشود؛ برخلاف دادههایی مانند int یا varchar که نوعهایی ساده بوده و تنها یک قطعه از اطلاعات خاصی را در خود نگهداری میکنند. بنابراین شاید این سؤال مطرح شود که چرا از این نوع داده پیچیده در SQL Server پشتیبانی شدهاست؟
- از سالهای نسبتا دور، از XML برای انتقال دادهها بین سیستمها و سکوهای کاری مختلف استفاده شدهاست.
- استفادهی گستردهای در برنامههای تجاری دارد.
- بسیاری از فناوریهای موجود از آن پشتیبانی میکنند.
برای مثال اگر با فناوریهای مایکروسافتی کار کرده باشید، به طور قطع حداقل در یک یا چند قسمت از آنها، مستقیما از XML استفاده شدهاست.
بنابراین با توجه به اهمیت و گستردگی استفاده از آن، بهتر است پشتیبانی توکاری نیز از آن داخل موتور یک بانک اطلاعاتی، پیاده سازی شده باشد. این مساله سهولت تهیه پشتیبانهای خودکار، بازیابی آنها و امنیت یکپارچه با SQL Server را به همراه خواهد داشت؛ به همراه تمام زیرساختهای مهیای در SQL Server.
روشهای مختلف ذخیره سازی XML در بانکهای اطلاعاتی رابطهای
الف) ذخیره سازی متنی
این روش نیاز به نگارش خاصی از SQL Server یا بانک اطلاعاتی الزاما خاصی نداشته و با تمام بانکهای اطلاعاتی رابطهای سازگار است؛ مثلا از فیلدهای varchar برای ذخیره سازی آن استفاده شود. مشکلی که این روش به همراه خواهد داشت، از دست دادن ارزش یک سند XML و برخورد متنی با آن است. زیرا در این حالت برای تعیین اعتبار آن یا کوئری گرفتن از آنها نیاز است اطلاعات را از بانک اطلاعاتی خارج کرده و در لایهای دیگر از برنامه، کار جستجو پردازش آنها را انجام داد.
ب) تجزیه XML به چندین جدول رابطهای
برای مثال یک سند XML را درنظر بگیرید که دارای اطلاعات شخص و خریدهای او است. میتوان این سند را به چندین فیلد در چندین جدول مختلف رابطهای تجزیه کرد و سپس با روشهای متداول کار با بانکهای اطلاعاتی رابطهای از آنها استفاده نمود.
ج) ذخیره سازی آنها توسط فیلدهای خاص XML
در این حالت با استفاده از فیلدهای ویژه XML میتوان از فناوریهای مرتبط با XML تمام و کمال استفاده کرد. برای مثال تهیه کوئریهای پیچیده داخل همان بانک اطلاعاتی بدون نیاز به تجزیه سند به چندین جدول و یا خارج کردن آنها از بانک اطلاعاتی و جستجوی بر روی آنها در لایهای دیگر از برنامه.
موارد کاربرد XML در SQL Server
کاربردهای مناسب
- اطلاعات، سلسله مراتبی و تو در تو هستند. XQuery و XPath در این موارد بسیار خوب عمل میکند.
- ساختار قسمتی از اطلاعات ثابت است و قسمتی از آن خیر. برای نمونه، یک برنامهی فرم ساز را درنظر بگیرید که هر فرم آن هر چند دارای یک سری خواص ثابت مانند نام، گروه و امثال آن است، اما هر کدام دارای فیلدهای تشکیل دهنده متفاوتی نیز میباشد. به این ترتیب با استفاده از یک فیلد XML، دیگری نیازی به نگران بودن در مورد نحوه مدیریت اسکیمای متغیر مورد نیاز، نخواهد بود.
نمونهی دیگر آن ذخیره سازی خواص متغیر اشیاء است. هر شیء دارای یک سری خواص ثابت است اما خواص توصیف کنندهی آنها از هر رکورد به رکوردی دیگر متفاوت است.
کاربردهای نامناسب
- کل اطلاعات را داخل فیلد XML قرار دادن. هدف از فیلدهای XML قرار دادن یک دیتابیس داخل یک سلول نیست.
- ساختار تعریف شده کاملا مشخص بوده و به این زودیها هم قرار نیست تغییر کند. در این حالت استفاده از قابلیتهای رابطهای متداول SQL Server مناسبتر است.
- قرار دادن اطلاعات باینری بسیار حجیم در سلولهای XML ایی.
تاریخچهی پشتیبانی از XML در نگارشهای مختلف SQL Server
الف) SQL Server 2000
در SQL Server 2000 روش (ب) توضیح داده شده در قسمت قبل، پشتیبانی میشود. در آن برای تجزیه یک سند XML به معادل رابطهای آن، از تابعی به نام OpenXML استفاده میشود و برای تبدیل این اطلاعات به XML از روش Select … for XML میتوان کمک گرفت. همچنین تاحدودی مباحث XPath Queries نیز در آن گنجانده شدهاست.
ب) SQL Server 2005
در نگارش 2005 آن، برای اولین بار نوع دادهای ویژه XML معرفی گشت به همراه امکان تعریف اسکیمای XML و اعتبارسنجی آن و پشتیبانی از XQuery برای جستجوی سریع بر روی دادههای XML داخل همان بانک اطلاعاتی، بدون نیاز به استخراج اطلاعات XML و پردازش مجزای آنها در لایهای دیگر از برنامه.
ج) SQL Server 2008 به بعد
در اینجا فاز نگهداری این نوع داده خاص شروع شده و بیشتر شامل یک سری بهبودهای کوچک در کارآیی و نحوهی استفاده از آنها میشود.
استفاده از XML با کمک SQLCLR
از SQL Server 2005 به بعد، امکان استفاده از کلیهی امکانات موجود در فضای نام System.Xml دات نت، در SQL Server نیز به کمک SQL CLR مهیا شدهاست. همچنین از SQL Server 2008 به بعد، امکانات فضای نام System.Xml.Linq و مباحث LINQ to XML نیز توسط SQL CLR پشتیبانی میشوند.
البته این امکانات در SQL Server 2005 نیز قابل استفاده هستند، اما اسمبلی شما unsafe تلقی میشود. پس از آزمایشات و بررسی کافی، فضای نام مرتبط با LINQ to XML و امکانات آن، به عنوان اسمبلیهایی امن و قابل استفاده در SQL Server 2008 به بعد، معرفی شدهاند.
مزایای وجود فیلد ویژه XML در SQL Server
پس از اینکه فیلدهای XML به صورت یک نوع داده بومی بانک اطلاعاتی SQL Server معرفی شدند، مزایای ذیل بلافاصله در اختیار برنامه نویسها قرار گرفت:
- امکان تعریف آنها به صورت یک ستون جدولی خاصی
- استفاده از آنها به عنوان یک پارامتر رویههای ذخیره شده
- امکان تعریف خروجی توابع scalar سفارشی تعریف شده به صورت XML
- امکان تعریف متغیرهای T-SQL از نوع XML
برای مثال در اینجا نحوهی تعریف یک جدول جدید دارای فیلدی از نوع XML را مشاهده میکنید:
CREATE TABLE xml_tab ( id INT, xml_col XML )
- امکان تعریف ایندکسهای XML ایی اضافه شدهاست.
چه نوع XML ایی را میتوان در فیلدهای XML ذخیره کرد؟
فیلدهای XML امکان ذخیره سازی دادههای XML خوش فرم را مطابق استاندارد یک XML، دارند. حداکثر اندازه قابل ذخیره سازی در یک فیلد XML دو گیگابایت است.
البته امکانات مهیای در SQL Server در بسیاری از موارد فراتر از استاندارد یک XML هستند. به این معنا که در فیلدهای XML میتوان Documents و یا Fragments را ذخیره سازی کرد. یک سند XML یا Document حاوی تنها یک ریشه اصلی است؛ اما یک Fragment میتواند بیش از یک ریشه اصلی را در خود ذخیره کند. یک مثال:
DECLARE @xml_tab TABLE (xml_col XML) -- document INSERT @xml_tab VALUES ('<person/>') -- fragment INSERT @xml_tab VALUES ('<person/><person/>') SELECT * FROM @xml_tab
DECLARE @xml_tab TABLE (xml_col XML) -- text only INSERT @xml_tab VALUES ('data data data .....') -- empty string INSERT @xml_tab VALUES ('') -- null value INSERT @xml_tab VALUES (null) SELECT * FROM @xml_tab
به علاوه باید دقت داشت که در SQL Server نوع دادهای XML برای ذخیره سازی دادهها بکار گرفته میشود. به این معنا که در اینجا پیشوندهای فضاهای نام XML بیمعنا هستند.
DECLARE @xml_tab TABLE (xml_col XML) INSERT @xml_tab VALUES ('<doc/>') INSERT @xml_tab VALUES ('<doc xmlns="http://www.doctors.com"/>') -- این سه سطر در عمل یکی هستند INSERT @xml_tab VALUES ('<doc xmlns="http://www.documents.com"/>') INSERT @xml_tab VALUES ('<dd:doc xmlns:dd="http://www.documents.com"/>') INSERT @xml_tab VALUES ('<rr:doc xmlns:rr="http://www.documents.com"/>') SELECT * FROM @xml_tab
Encoding ذخیره سازی دادههای XML
SQL Server امکان ذخیره سازی اطلاعات متنی را به فرمت UFT8، اسکی و غیره، دارد. اما جهت پردازش فیلدهای XML و ذخیره سازی آنها از Collation پیش فرض بانک اطلاعاتی کمک خواهد گرفت. البته ذخیره سازی نهایی آن همیشه با فرمت UCS2 است (یونیکد دو بایتی).
DECLARE @xml_tab TABLE (id INT, xml_col XML) INSERT INTO @xml_tab VALUES ( 5, N'<?xml version="1.0" encoding="utf-8"?> <doc1> <row name="vahid"></row> </doc1> ')
XML parsing: line 1, character 38, unable to switch the encoding
برای حل این مشکل باید N ابتدای رشته را حذف کرد. روش دوم، معرفی و استفاده از utf-16 است بجای utf-8 در ویژگی encoding.
همچنین در این حالت اگر encoding را utf-16 معرفی کنیم و ابتدای رشته در حال ذخیره سازی N قرار نگیرد، باز با خطای unable to switch the encoding مواجه خواهیم شد.
نحوهی ذخیره سازی اطلاعات XML ایی در SQL Server
SQL Server فرمت اطلاعات XML وارد شده را حفظ نمیکند. برای مثال اگر قطعه کد زیر را اجرا کنید
DECLARE @xml_tab TABLE (id INT, xml_col XML) INSERT INTO @xml_tab VALUES ( 5, '<?xml version="1.0" encoding="utf-8"?><doc1><row name="vahid"></row></doc1>' ) SELECT * FROM @xml_tab
<doc1> <row name="vahid" /> </doc1>
ذخیره سازی دادههایی حاوی کاراکترهای غیرمجاز XML
اطلاعات دنیای واقعی همیشه به همراه اطلاعات تک کلمهای ساده نیست. ممکن است نیاز شود انواع و اقسام حروف و تگها نیز در این بین به عنوان داده ذخیره شوند. روش حل استاندارد آن بدون نیاز به دستکاری اطلاعات ورودی، استفاده از CDATA است:
DECLARE @xml_tab TABLE (id INT, xml_col XML) INSERT INTO @xml_tab VALUES ( 5, '<person><![CDATA[ 3 > 2 ]]></person>' ) SELECT * FROM @xml_tab
<person> 3 > 2 </person>
محدودیتهای فیلدهای XML
- امکان مقایسه مستقیم را ندارند؛ بجز مقایسه با نال. البته میتوان XML را تبدیل به مثلا varchar کرد و سپس این داده رشتهای را مقایسه نمود. برای مقایسه با null توابع isnull و coalesce نیز قابل بکارگیری هستند.
- order by و group by بر روی این فیلدها پشتیبانی نمیشود.
- به عنوان ستون کلید قابل تعریف نیست.
- به صورت منحصربفرد و unique نیز قابل علامتگذاری و تعریف نیست.
- فیلدهای XML نمیتوانند دارای collate باشند.
ثبت و نگهداری تاریخ خورشیدی در SQL Server از دیرباز یکی از نگرانیهای برنامهنویسان و
طراحان پایگاه دادهها بوده است. در این نوشتار، راهکار تعریف یک DataType در SQL Server 2012 به روش CLR آموزش داده
خواهد شد.
در ویژوال استودیو یک پروژهی جدید از نوع SQL Server Database Project
به شکل زیر ایجاد کنید:
متن موجود در صفحهی بازشده را کاملاً حذف کرده و با کد زیر جایگزین کنید.
(در کد زیر همهی توابع لازم برای مقداردهی به سال، ماه، روز، ساعت، دقیقه و ثانیه و البته گرفتن مقدار از آنها، تبدیل تاریخ خورشیدی به میلادی، گرفتن تاریخ به تنهایی، گرفتن زمان به تنهایی، افزایش یا کاهش زمان برپایهی یکی از متغیرهای زمان و بررسی و اعتبارسنجی انواع بخشهای زمان گنجانده شده است. در صورت پرسش یا پیشنهاد روی هر کدام در قسمت نظرات، پیام خود را بنویسید.)
using System; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; [Serializable()] [SqlUserDefinedType(Format.Native)] public struct JalaliDate : INullable { private Int16 m_Year; private byte m_Month; private byte m_Day; private byte m_Hour; private byte m_Minute; private byte m_Second; private bool is_Null; public Int16 Year { get { return (this.m_Year); } set { m_Year = value; } } public byte Month { get { return (this.m_Month); } set { m_Month = value; } } public byte Day { get { return (this.m_Day); } set { m_Day = value; } } public byte Hour { get { return (this.m_Hour); } set { m_Hour = value; } } public byte Minute { get { return (this.m_Minute); } set { m_Minute = value; } } public byte Second { get { return (this.m_Second); } set { m_Second = value; } } public bool IsNull { get { return is_Null; } } public static JalaliDate Null { get { JalaliDate jl = new JalaliDate(); jl.is_Null = true; return (jl); } } public override string ToString() { if (this.IsNull) { return "NULL"; } else { return this.m_Year.ToString("D4") + "/" + this.m_Month.ToString("D2") + "/" + this.m_Day.ToString("D2") + " " + this.Hour.ToString("D2") + ":" + this.Minute.ToString("D2") + ":" + this.Second.ToString("D2"); } } public static JalaliDate Parse(SqlString s) { if (s.IsNull) { return Null; } System.Globalization.PersianCalendar pers = new System.Globalization.PersianCalendar(); string str = Convert.ToString(s); string[] JDate = str.Split(' ')[0].Split('/'); JalaliDate jl = new JalaliDate(); jl.Year = Convert.ToInt16(JDate[0]); byte MonthsInYear = (byte)pers.GetMonthsInYear(jl.Year); jl.Month = (byte.Parse(JDate[1]) <= MonthsInYear ? (byte.Parse(JDate[1]) > 0 ? byte.Parse(JDate[1]) : (byte)1) : MonthsInYear); byte DaysInMonth = (byte)pers.GetDaysInMonth(jl.Year, jl.Month); ; jl.Day = (byte.Parse(JDate[2]) <= DaysInMonth ? (byte.Parse(JDate[2]) > 0 ? byte.Parse(JDate[2]) : (byte)1) : DaysInMonth); if (str.Split(' ').Length > 1) { string[] JTime = str.Split(' ')[1].Split(':'); jl.Hour = (JTime.Length >= 1 ? (byte.Parse(JTime[0]) < 23 && byte.Parse(JTime[0]) >= (byte)0 ? byte.Parse(JTime[0]) : (byte)0) : (byte)0); jl.Minute = (JTime.Length >= 2 ? (byte.Parse(JTime[1]) < 59 && byte.Parse(JTime[1]) >= (byte)0 ? byte.Parse(JTime[1]) : (byte)0) : (byte)0); jl.Second = (JTime.Length >= 3 ? (byte.Parse(JTime[2]) < 59 && byte.Parse(JTime[2]) >= (byte)0 ? byte.Parse(JTime[2]) : (byte)0) : (byte)0); } else { jl.Hour = 0; jl.Minute = 0; jl.Second = 0; } return (jl); } public SqlString GetDate() { return this.m_Year.ToString("D4") + "/" + this.m_Month.ToString("D2") + "/" + this.m_Day.ToString("D2"); } public SqlString GetTime() { return this.Hour.ToString("D2") + ":" + this.Minute.ToString("D2") + ":" + this.Second.ToString("D2"); } public SqlDateTime ToGregorianTime() { System.Globalization.PersianCalendar pers = new System.Globalization.PersianCalendar(); return SqlDateTime.Parse(pers.ToDateTime(this.Year, this.Month, this.Day, this.Hour, this.Minute, this.Second, 0).ToString()); } public SqlString JalaliDateAdd(SqlString interval, int increment) { System.Globalization.PersianCalendar pers = new System.Globalization.PersianCalendar(); DateTime dt = pers.ToDateTime(this.Year, this.Month, this.Day, this.Hour, this.Minute, this.Second, 0); string CInterval = interval.ToString(); bool isConvert = true; switch (CInterval) { case "Year": dt = pers.AddYears(dt, increment); break; case "Month": dt = pers.AddMonths(dt, increment); break; case "Day": dt = pers.AddDays(dt, increment); break; case "Hour": dt = pers.AddHours(dt, increment); break; case "Minute": dt = pers.AddMinutes(dt, increment); break; case "Second": dt = pers.AddSeconds(dt, increment); break; default: isConvert = false; break; } if (isConvert == true) { this.Year = (Int16)pers.GetYear(dt); this.Month = (byte)pers.GetMonth(dt); this.Day = (byte)pers.GetDayOfMonth(dt); this.Hour = (byte)pers.GetHour(dt); this.Minute = (byte)pers.GetMinute(dt); this.Second = (byte)pers.GetSecond(dt); } return this.m_Year.ToString("D4") + "/" + this.m_Month.ToString("D2") + "/" + this.m_Day.ToString("D2") + " " + this.Hour.ToString("D2") + ":" + this.Minute.ToString("D2") + ":" + this.Second.ToString("D2"); } }
از منوهای بالا روی منوی Bulild و سپس گزینهی Publish prgJalaliDate کلیک کتید:
در پنجرهی بازشده روی دکمهی Edit کلیک کنید سپس تنظیمات مربوط به اتصال به پایگاه داده را انجام دهید.
روی دکمهی OK کلیک کنید و سپس در پنجرهی اولیه، روی دکمهی Publish کلیک کتید:
به همین سادگی، DataType مربوطه در SQL Server 2012 ساخته میشود. خبر خوش اینکه شما میتوانید با راستکلیک روی نام پروژه و انتخاب گزینهی Properties در قسمت Project Setting تنظیمات مربوط به نگارش SQL Server را انجام دهید. (از نگارش 2005 به بعد در VS 2012 پشتیبانی میشود.)
اکنون زمان آن رسیده است که DataType ایجادشده را در SQL Server 2012 بیازماییم. SQL Server را باز کنید و دستور زیر را در آن اجرا کتید.
USE Northwind GO CREATE TABLE dbo.TestTable ( Id int NOT NULL IDENTITY (1, 1), TestDate dbo.JalaliDate NULL ) ON [PRIMARY] GO
اکنون چند رکورد درون این جدول درج میکنیم:
Insert into TestTable (TestDate) Values ('1392/02/09'),('1392/02/09 22:40'),('1392/12/30 22:40')
این خطا به این خاطر است که CLR را در SQL Server فعال نکرده ایم. جهت فعالکردن CLR دستور زیر را اجرا کنید:
sp_configure 'clr enabled', 1 Reconfigure
Insert into TestTable (TestDate) Values ('1392/02/09'),('1392/02/09 22:40'),('1392/12/30 22:40')
اکنون زمان آن رسیده است که توسط یک پرسوجو، همهی توابعی که در سیشارپ برای این نوع داده نوشتیم، بیازماییم. پرسوجوی زیر را اجرا کنید:
Select TestDate.ToString() as JalaliDateTime, TestDate.GetDate() as JalaliDate, TestDate.GetTime() as JalaliTime, TestDate.ToGregorianTime() as GregorianTime, TestDate.JalaliDateAdd('Day',1) JalaliTomorrow, TestDate.Month as JalaliMonth from TestTable
نیازی به گفتن نیست که میتوانید به سادگی از توابع مربوط به DateTime در SQL Server بهره ببرید. برای مثال برای به دست آوردن فاصلهی میان دو روز از پرسوجوی زیر استفاده کنید:
Declare @a JalaliDate = '1392/02/07 00:00:00' Declare @b JalaliDate = '1392/02/05 00:00:00' SELECT DATEDIFF("DAY",@b.ToGregorianTime(),@a.ToGregorianTime()) AS DiffDate
شاد و پیروز باشید.
if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); }
//if (env.IsDevelopment()) //{ //app.UseDeveloperExceptionPage(); //} //else //{ app.UseExceptionHandler("/Error"); //}
@page "/counter" <PageTitle>Counter</PageTitle> <h1>Counter</h1> <p role="status">Current count: @currentCount</p> <button @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; throw new Exception("This is my Exception !!"); } }