افزودن یک DataType جدید برای نگهداری تاریخ خورشیدی - 3
نویسنده: حامد قنادی
تاریخ: ۱۳۹۲/۰۲/۱۳ ۱۳:۲۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
Declare @MyDate JalaliDate = '1392/02/11 21:38:24'
Select @MyDate.ToString() as MyDateTime
, @MyDate.GetDate() as MyDate
, @MyDate.GetTime() as MyTime
, @MyDate.Year as MyYear
, @MyDate.Month as MyMonth
, @MyDate.Day as MyDay
, @MyDate.Hour as MyHour
, @MyDate.Minute as MyMinute
, @MyDate.Second as MySecond
, @MyDate.JalaliDateAdd('Year',1) as NextYear
, @MyDate.JalaliDateAdd('Month',1) as NextMonth
, @MyDate.JalaliDateAdd('Day',1) as NextDay
, @MyDate.JalaliDateAdd('Hour',1) as NextHour
, @MyDate.JalaliDateAdd('Minute',1) as NextMinute
, @MyDate.JalaliDateAdd('Second',1) as NextSecondبا این همه، همانسان که در پرسوجوی بالا هم میبینید؛ ناگزیر شدم تاریخ و زمان را خودم وارد کنم و هرآینه در واقعیت شما جهت پرسوجو روی زمان کنونی، ناگزیر به استفاده از یک تابع برای تبدیل تقویم میلادی به خورشیدی هستیم. به نظر شما بهتر نیست دست به کار شویم و تابعی برای تبدیل تاریخ میلادی به خورشیدی بنویسیم؟
برای اینکار پروژهای را که در دو درس 1 ساختیم باز کنید و سپس روی نام پروژه در Solution Explorer راستکلیک کرده و Add New Item را انتخاب کنید.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static JalaliDate GetCurrentDateTime()
{
System.Globalization.PersianCalendar pers = new System.Globalization.PersianCalendar();
DateTime CurrentDate = DateTime.Now;
JalaliDate jl;
jl.Year = (Int16)pers.GetYear(CurrentDate);
jl.Month = (byte)pers.GetMonth(CurrentDate);
jl.Day = (byte)pers.GetDayOfMonth(CurrentDate);
jl.Hour = (byte)pers.GetHour(CurrentDate);
jl.Minute = (byte)pers.GetMinute(CurrentDate);
jl.Second = (byte)pers.GetSecond(CurrentDate);
return jl;
}
}Declare @MyDate JalaliDate = dbo.GetCurrentDateTime()
Select dbo.GetCurrentDateTime().ToString()
public DateTime AddDate { set; get; }
[NotMapped] // فیلد محاسباتی سمت برنامه که در بانک اطلاعاتی قرار نخواهد گرفت
public string PersianDate
{
get { return MyDateConverter(AddDate); }
}در code first از ویژگی NotMapped استفاده کنید تا بتونید با استفاده از تابع کمکی تبدیل تاریخ خودتون راحت این تبدیلات رو انجام بدید. در بانک اطلاعاتی DateTime استاندارد رو ذخیره کنید، در سمت کدها برای مسایل نمایشی از خاصیت PersianDate که NotMapped تعریف شده، میشه استفاده کرد. به علاوه روی DateTime استاندارد راحت میشه کوئریهای LINQ رو اجرا کرد بدون محدودیت. زمانیکه مثلا یک List تهیه شد، قسمت بعدی، کار نمایشی است که از خاصیت NotMapped میشه کمک گرفت. این روش با تمام بانکهای اطلاعاتی کار میکنه.
[Column(TypeName = "xml")]
public string XmlValue { get; set; }
[NotMapped]
public XElement XmlValueWrapper
{
get { return XElement.Parse(XmlValue); }
set { XmlValue = value.ToString(); }
}روش عمومی کار با نوعهای خاصی که در EF تعریف نشدن، استفاده از ویژگی Column و مشخص کردن Type آن است؛ مانند مثالی که در بالا ملاحظه میکنید. البته این نوع خاص، در سمت کدها باید به صورت رشته تعریف شود. مثلا از سال 2005 به این طرف فیلد XML به SQL Server اضافه شده. اما نمیشود ازش در EF به همون شکل XML استفاده کرد. باید تبدیلش کنی به String تا قابل استفاده بشه. یک نمونه دیگرش نوع خاص Spatial هست که در نگارشهای اخیر SQL Server اضافه شده (geography و geometry). این مورد فقط از EF 5.0 به بعد پشتیبانی توکاری ازش ارائه شده. یا برای hierarchyID در EF معادلی وجود نداره. برای تعریف این مورد نیز در یک مدل باید از string استفاده کرد.
بعد اگر این نوع خاص (که الان به صورت رشته دریافت شده) قابل نگاشت به نوعی مشخص در سمت کدهای برنامه بود (یعنی صرفا یک رشته ساده نبود) مثلا میشود از ویژگی NotMapped برای تبدیل آن و تعریف آن به شکل یک فیلد محاسباتی استفاده کرد.
SELECT id, TestDate.ToString() FROM TestTable;