آموزش Code First Data Annotations - بخش چهارم
بسم الله الرحمن الرحیم
برای مشاهده سایر بخش های دوره آموزش Code First Data Annotations از طریق لینکهای زیر اقدام نمایید.
بخش چهارم
Index
ایندکس گزاری بر روی جداول
خاصیت Index در EF6.1 معرفی شده است و فقط توسط این نسخه از Entity Framework می توانید این کار را انجام دهید. اگر از نسخه های قدیمی Entity Framework استفاده می کنید نمی توانید این کار را انجام دهبد.
شما می توانید بر روی یک یا چند ستون از جدول خود با استفاده از IndexAttribute ایندکس گذاری کنید.
اضافه کردن این خاصیت به یک یا چند پراپرتی باعث می شود EF در زمان ایجاد دیتابیس یا اگر شما از Code First Migrations استفاده کنید scaffold ایندکس های مربوطه را ایجاد کند.
مثال، در زیر index بر روی ستون های Rating و Posts ایجاد شده است.
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
[Index]
public int Rating { get; set; }
public int BlogId { get; set; }
}
در ایندکس ها نامگذاری ها به صورت پیش فرض به شکل IX_<property name> (مثلا IX_Rating برای مثال بالا است)، اما شما نیز می توانید بر روی ایندکس ها نامگذاری خود را اعمال کنید.
مثال:
[Index("PostRatingIndex")]
public int Rating { get; set; }
به صورت پیش فرض ایندکس ها non-unique هستند اما شما می توانید از خاصیت IsUnique در پارامتر index برای تعیین unique بودن یا نبودن ایندکس استفاده کنید:
[Index("PostRatingIndex")]
public int Rating { get; set; }
Multiple-Column Indexes
ایندکس هایی که با چندین ستون جدول خواهید ایجاد شوند می بایست دارای یک نام باشند . هنگامی که شما یک ایندکس چند ستونی ایجاد می کنید باید ترتیب این ایندکس ها را نیز مشخص کنید.
مثال:
در اینجا یک ایندکس دو ستونی به وسیله فیلدهای Rating و BlogId ایجاد شده است، نام ایندکس ما IX_BlogAndRating است که BlogId ایندکس اول و Rating ایندکس دوم خواهد بود.
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
[Index("IX_BlogIdAndRating", 2)]
public int Rating { get; set; }
[Index("IX_BlogIdAndRating", 1)]
public int BlogId { get; set; }
}
Relationship Attributes: InverseProperty and ForeignKey
در کلاس Blog نام کلید اصلی را تغییر دهید، مشکلی در کلاس Post برای relationship ایجاد خواهد شد.
هنگام دیتابیس ایجاد می شود، code first مشاهده می کند که پراپرتی BlogId در کلاس Post قرار دارد، همچنین بر اساس قراردادی که نام کلاس را به علاوه کلمه “id” به عنوان کلید خارجی مشخص می کند به دنبال این کلید خارجی از جدول Blog می گردد. اما در کلاس Blog پراپرتی BlogId وجود ندارد.
برای حل این مشکل باید از Foreign DataAnnotation استفاده کنید تا به Code First اطلاع دهید کلید خارچی چه پراپرتی است تا بر اساس آن relationship مربوطه بین دو کلاس ایجاد شود.
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime DateCreated { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
[ForeignKey("BlogId")]
public Blog Blog { get; set; }
public ICollection<Comment> Comments { get; set; }
}
Constraint در دیتابیس نشان می دهد که relationship بین InternalBlogs.PrimaryTrackingKey و Posts.BlogIdاست.
InverseProperty زمانی مورد استفاده قرار می گیرد که چندین relationships بین کلاس ها وجود داشته باشد
در کلاس Post، همانند نویسنده یک پست که مشخص شده است، ممکن است شما بخواهید بدانید چه کسی آن را ویرایش کرده است. در اینجا دو پراپرتی navigation برای کلاس Post وجود دارد.
public Person CreatedBy { get; set; }
public Person UpdatedBy { get; set; }
شما همچنین در کلاس Person این پراپرتی ها را باید معرفی کنید. کلاس Person دارای پراپرتی هایی برای پیمایش و بازگشت به کلاس Post است، یک پیمایش گر برای نویسندگان پستها و یکی نیز برای کسانی که پست را updated کرده اند.
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public List<Post> PostsWritten { get; set; }
public List<Post> PostsUpdated { get; set; }
}
Code First نمی تواند به خودی خود پراپرتی های هر دو کلاس را مرتبط کند. در جدول Posts باید دو کلید خارجی، یکی برای CreatedBy و دیگری برای UpdatedBy وجود داشته باشد اما Code First 4 پراپرتی کلید خارجی Person_Id, Person_Id1, CreatedBy_Id and UpdatedBy_Id ایجاد می کند.
برای حل این مشکل می توانید از InverseProperty annotation برای مشخص کردن و تعیین پراپرتی های مورد نظر استفاده کنید.
[InverseProperty("CreatedBy")]
public List<Post> PostsWritten { get; set; }
[InverseProperty("UpdatedBy")]
public List<Post> PostsUpdated { get; set; }
به دلیل اینکه پراپرتی PostsWritten در Person می داند که این یک اشاره گر به Post type است، این یک relationship به Post.CreatedBy ایجاد می کند. همچنین PostsUpdated به Post.UpdatedBy متصل می شود. در نهایت Code First کلیدهای خارجی اضافی ایجاد نمی کند.