در نوشته های زیر چگونگی نوشتن کلاس های Entity در رویکرد Code First را نشان دادیم . گفتیم که باید یک رشته از قاعده را در نوشتن آنها دنبال کنیم وگرنه در زمان کامپایل خطایی نشان داده می شود. برای نمونه ویژگی که  Primary Key را نشان می دهد یا باید Id و یا باید ClassNameId مانند UserId باشد. همچنین چگونگی نوشتن Foriegn Key و ایجاد رابطه ها نیز دارای قاعده ویژه خودشان بوند.

در نوشته ایجاد مدل و مفهوم و کاربرد DbContext در Entity Framework گفتیم که دو روش برای پیاده سازی Model در برنامه های Dot Net به دو روش Code First و EF Designer می توانیم مدل پایگاه داده را پیاده سازی کنیم. در رویکرد Code First بوسیله شی گرایی کلاس های Entity را می نویسم که هر کلاس یک جدول پایگاه داده را نشان می دهد.

Data Annotation در Dot Net چیست

;n زیر نمونه ای از مدل را که شامل دو کلاس Post و Blog را نشان می دهد. ویژگی های Id در هر دو همان Primary Key هستند. اگر بخواهیم چیزی به جز Id را بنوسیم چه کاری باید انجام دهیم؟ برای چنین کاری باید Data Annotation ها را به کار بگیریم. Data Annotation ویژگی هایی از Dot Net هستند که به کلاس های Entity یا ویژگی های آنها واگذار می شوند تا بتوانیم قاعده ها (روند و دستورهای پیش فرض Code First) را بهم زنیم و آنگونه که دلخواه مان است ویژگی ها و دیگر مولفه های کلاس Entity را بنویسیم.

پس به زبان ساده، Data Annotation بر هم زدن دستورهای پیش فرض Dot Net برای نوشتن کلاس های Entity در Entity Framework است به گونه ای که آن پیچیدگی های نوشتن کلاس ها از میان برداشته شده و به سادگی و با خوانایی بهتری می توانیم مدل ها را درون Code First بنویسیم. Data Annotation همچنین در ASP.NET MVC (در Dot Net و Dot Net Core) نیز به کار گرفته می شوند و فضای نام آنها System.ComponentModel.DataAnnotations و System.ComponentModel.DataAnnotations.Schema است. بنابراین پیش از هر چیز این دو فضای نام باید به فایل برنامه پیوست شوند.

Data Annotation تنها ابزار Dot Net برای نوشتن کلاس های Entity و ویژگی های آن نیست (همان ستون های جدول) بلکه در نوشته های پیش رو با ابزار دیگری به نام Fluent API است که گزینه های پیکربندی بیشتری را برای نوشتن مدل Code First فراهم کرده است. هر دو اینها به ساده سازی نوشتن کلاس های Entity  کمک می کنند تا پیچیدگی های نوشته های پیشین را کنار بگذاریم.

ویژگی های Data Annotation درون دو فضای نام بالا هستند که می توانیم آنها را برای ایجاد کلید اصلی (Primary Key)، کلید خارجی (Forigen Key) و همچنین می توانیم نشان دهیم که باید برای یک ویژگی کلاس (یا همان ستون جدول) مقدار وارد شده و نمی توان آن را بدون مقدار رها کرد. این در ASP.NET  یا در برنامه نویسی GUI کاربردی است، زمانی که اگر فیلدی از HTML یا GUI خالی رها شود، یک Error نشان داده می شود.

ویژگی های درون فضای نام System.ComponentModel.Annotations

۱ – Key Attribute

اگر Key بالای یکی از ویژگی های کلاس Entity نوشته شود، آن ویژگی با هر نامی که داشته باشد، نام دلخواه شما برای ستون گزینش می شود. بنابراین با نوشتن [Key] بالای ویژگی کلاس آن ویژگی نیازی ندارد روش همیشگی نامگذازی Primary Key را دنبال کند. در کد زیر چون [Key] بالای ویژگی OrderNumber از کلاس Order نوشته شده است، پس آن از این پس کلید اصلی جدول پایگاه داده خواهد بود. همچنین می بینید که دیگر نیازی به روش نامگذاری Id یا OrderId نیست و چون [Key] نوشته شده است، پس دیگر خطایی نشان داده نمی شود.

کلید اصلی شامل چندین ویژگی کلاس Entity

در پایگاه داده ها چندین کلید می توانند با یکدیگر کلید اصلی را ایجاد کنند، پس چگونه باید این را به کلاس های Entity بگوییم که برای نمونه دو ویژگی تو همراه با هم کلید اصلی را ایجاد می کنند. در این گونه باید بالای هر کدام از ویژگی های کلاس که می خواهیم بخشی از کلید اصلی باشند باید [Key] را بنویسیم تا Dot net بفهمد که چندین ویژگی کلاس با یکدیگر کلید اصلی جدول را ایجاد می کنند. شکل زیر نمونه ای را نشان می دهد که در کلاس Passport دو ویژگی PassportNumber و IssuingCountry کلید اصلی را ایجاد می کنند زیرا شاید شماره (شناسه) گذرنامه دو نفر از دو کشور یکسان و همانند هم باشد، پس نام کشور نیز بخشی از کلید اصلی می شود.

پس از نوشتن ویژگی Key در بالای هر کدام از ویژگی های کلاس که می خواهیم بخشی از کلید اصلی باشند، باید ویژگی دیگری به نام Column از فضای نام  را نیز زیر Key بنویسیم. این کار برای این است که می خواهیم بوسیله کدهای سی شارپ ستون آمیخته (Composit) از دو ویژگی کلاس را ایجاد کنیم. پس برابر با کد زیر باید ویژگی Column را همراه با پارامتر Order و به شیوه های [(Column=(Order=1] و [(Column=(Order=1] بالای دو ویژگی دلخواه درون کلیدی اصلی بنویسیم.

اگر ویژگی Column را ننویسید و تنها به نوشتن Key بسنده کنید، پس در زمان کامپایل (برگردان یا ترجمه برنامه به کد ماشین) یک Exception به نام InvalidOperationException رخ می دهد. در مطلب پیش بوسیله ویژگی Column در پیوند با کلید بیرونی (خارجی) آموزش داده ایم، زیرا کلیدهای بیرونی نیز می توانند شامل بیش از یک ستون باشند. به یاد داشته باشید که ویژگی کلاس Entity به یک ستون جدول و خود کلاس Entity به یک جدول نگاشت داده می شوند.

۲ – Minmum – Maximum Length

در نام نویسی سایت ها دیده اید که گذرواژه باید میان ۶ تا ۱۵ کاراکتر باشد. در اینگونه نمونه ها که نیاز است تا رشته (String) ورودی برای یک فیلد میان کمینه و بیشینه باشد، باید ویژگی های Minimum و Maxmum را به کار ببرید. در پایگاه داده نیز به همین گونه است که می توان با کمک گرفتن از Contsrant ها، بگویید که مقدار ورودی برای یک ستون میان یک بازه باشد. برای نمونه سن کاربران و کارمندان باید یا اینکه نمره دانش آموز و دانشجو باید میان بازه درستی وارد شود. البته این دو ویژگی هیچ گونه دگرگونی (تغییری) روی پایگاه داده ندارند و تنها در سمت کلاینت (مرورگر) داده وارد شده را سنجیش درستی می کنند که آیا در بازه دلخواه شما (برنامه نویس) هست یا نه؟

در کد زیر تنها ویژگی Maximum نوشته شده است، بنابراین پس از نگاشت از سی شارپ به SQL، ستونی به گونه (VARCHAR(50 ایجاد می شود، زیرا آشکارا در کد سی شارپ گفته ایم که بیشینه ای که ویژگی (یا همان ستون) StudentName می تواند دریافت کند، برابر با ۵۰ کاراکتر است. همین مورد را می توانیم برای Minimum بگوییم که اگر ویزگی Minimum به شیوه زیر و به تنهایی نوشته شد، پس دست کم باید به ۸ کاراکتر وارد شود، وگرنه خطا نشان داده خواهد شد.

همانطور که می بینید ویژگی های Data Annotation میان براکت های باز و بسته نوشته می شوند و مقدار آنها میان پرانتزها نوشته خواهد شد.

در کد زیر هر دو ویژگی Minimum و Maximum با مقدار نوشته شده اند. در این گونه پایگاه داده اندازه VARCHAR را برابر با مقدار ویژگی Maximum قرار می دهد. بنابراین در کد زیر، اندازه ستون BloggerName برابر با ۱۰ می شود. البته این که بخوایم مقدار ورودی را میان یک بازه (Range) مشخص کنیم، باید آن را بوسیله ویژگی دیگری به نام Range انجام دهیم که در ادامه آموزش داده ایم.

همچنین می توانیم همانند زیر پیامی (Message) را نیز مشخص کنیم که در صورت برآورده نشدن ویزگی (برای نمونه دست کم ۸ کاراکتر ورودی)، این پیام بر روی Web Page یا GUI نشان داده شود. همانگونه که در شکل زیر می بینید، پیام بوسیله ErrorMessage برای هر ویژگی (در اینجا Maximum) نوشته شده است. پس اگر ویزگی Maximum یا بیشینه ۱۰ کاراکتر را برآورده نشود (۱۱ یا بیشتر وارد شود) پس پیام خطا نشان داده می شود.

۳ – Range Attribute

این ویژگی یک بازه از مقدارها را نشان می دهد که داده ورودی فیلد باید درون این بازه باشد. همانگونه که می بینید مقدارهای بازه می توانند از هر گونه شماره های صحیح و ممیز شناور (مثبت و منفی) و داده های تاریخ و زمان (Date and Time – Timestamp) باشند. همچنین می بینید که می توان بیش از یک گزینه را میان پرانتزهای ویژگی Data Annonation بنویسیم. در دستور نخست، بازه میان شماره های ۱۰ تا ۱۰۰۰ است و در سومین میان گونه Date است.

۴ – StringLength

در پیاده سازی پایگاه داده، برای ستون های رشته (VARCHAR) یک اندازه باید تعیین شود. ویژگی StringLength نیز به همین گونه رفتار می کند. این ویژگی همانند Maximum است. یک تفاوت میان StringLength و Maximum در این است که Minimum و Maximum برای وادار کردن به ورودی بر پایه کمینه یا بیشینه ورودی است ولی StringLength تعداد کاراکترهای یک فیلد (ستون) را مشخص می کند. بنابراین در کد زیر چون ۱۵۰ برای StringLength برای ستون Title وارد شده، پس این ستون تا ۱۵۰ کاراکتر را می تواند داشته باشد. اگر نه StringLength و نه Maximum را نمی نوشتیم، پس بی شمار رشته می توانیم درون ستون وارد کنیم.

در کد زیر درون StringLength کمینه کاراکتر ورودی را نیز نشان داده ایم. پارامتر MinimumLength که درون خود StringLength نوشته شده است، هیچگونه اثری به جدول پایگاه ندارد و تنها در سمت کاربر به کار می رود تا در فرم اچ تی ام ال یا GUI اگر کاربر کمتر از ۵ کاراکتر وارد کرد، خطا نشان داده شود. بنابراین این سنجش درستی ورودی (Input Validation) در کلاینت (سمت کاربر) و پیش از فرستاده شدن به سرور (پایگاه داده) انجام می شود.

۴ – Required

Required واپسین ویژگی است که از فضای نام System.ComponentModel.DataAnnotations آموزش می دهیم. از نام ویژگی پیدا است که ستون (فیلد) می بایست پر شود و بی مقدار فرستاده نشود. با این نمونه بسیار روبرو شده اید، مانند فیلدهای نام کاربری، گذرواژه، رایانامه و دیگر نمونه ها که در وب یا برنامه های GUI می بینید.

در کد بالا نخست ویژگی BookId کلاس (که از پیش فرض های Entity Framework نیز پیروی می کند را با ویژگی Key کلید اصلی گرفته ایم. سپس دو ویژگی StringLength و Required به دنبال هم برای Title نوشته شده اند، پس می توانیم بیش از یک ویژگی را نیز به کار ببریم. آنچه که در بخش نخست گفتیم، دید خوبی از Data Annotation داد و دیدید که کار را تا چه اندازه ساده و روان کرد. در مطلب های پیش رو جنبه های دیگر آموزش داده شده اند.

ویژگی های Data Annotation را می توانیم در دو گروه بدانیم، یک گروه که جدول و ستون های پایگاه داده را دگرگون می کنند (تغییر می دهند) که آن ها را نوشته پیش رو Data Annotation در Entity Framework – بخش دوم گفته ایم که شامل Key و Table و Cloumn و دیگر است. در برابر آنها دسته ای هستند که در سمت کلاینت برای سنجش درستی (Validation) ورودی کاربر، به کار گرفته می شوند. این دسته همان هایی هستند که بخشی از آنها را در این نوشته و بخشی دیگر را در نوشته Data Annotation در Entity Framework – بخش سوم می خوانید.