تعریف کلاس های جداول به روش Fluent API و Data Annotations
در روش کد فرست که ابتدا نسبت به ایجاد کلاس های معادل جداول بانک اطلاعات اقدام می کنیم ، به روش زیر می توان نسبت به تعریف روابط بین جداول و تعریف رفتار حذف اقدام کنیم . در ادامه مثالی از روش تعریف جداول و ارتباطات آنها به روش Fluent API آورده شده است :
تعریف جداول به روش Fluent API :
در این مثال، فرض کنید که هر مربی یک سبک ورزشی دارد و شناسایی مربیان با کلید ترکیبی CoachId و SportStyle انجام میشود.
ابتدا مدلهای Parent و Child را تعریف میکنیم:
public class Coach
{
public int CoachId { get; set; }
public string SportStyle { get; set; }
public string Name { get; set; }
public ICollection<Child> Children { get; set; }
}
public class Child
{
public int ChildId { get; set; }
public string Name { get; set; }
public int CoachId { get; set; }
public string SportStyle { get; set; }
public Coach Coach { get; set; }
}
سپس در فایل DbContext، کلید ترکیبی و روابط را با استفاده از Fluent API تعریف میکنیم:
public class MyDbContext : DbContext
{
public DbSet<Coach> Coaches { get; set; }
public DbSet<Child> Children { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// تعریف کلید ترکیبی برای Coach
modelBuilder.Entity<Coach>()
.HasKey(c => new { c.CoachId, c.SportStyle });
// تعریف کلید داخلی برای Child
modelBuilder.Entity<Child>()
.HasKey(c => c.ChildId);
// تعریف رابطه یکبهچند بین Coach و Child
modelBuilder.Entity<Child>()
.HasOne(c => c.Coach)
.WithMany(p => p.Children)
.HasForeignKey(c => new { c.CoachId, c.SportStyle })
.OnDelete(DeleteBehavior.Restrict);
}
}
در این مثال:
- کلید ترکیبی برای
Coachبا استفاده ازHasKeyو ترکیبCoachIdوSportStyleتعریف شده است. - کلید داخلی برای
Childبا استفاده ازHasKeyوChildIdتعریف شده است. - رابطهی یکبهچند بین
CoachوChildبا استفاده ازHasOne,WithManyوHasForeignKeyو ترکیب کلیدهایCoachIdوSportStyleتعریف شده است. OnDelete(DeleteBehavior.Restrict)رفتار حذف را تنظیم میکند که اجازه نمیدهد در صورت حذف مربی (Coach)، کودکان (Child) مرتبط حذف شوند.
تعریف جداول به روش Data Annotations :
در صورتی که از تعریف رفتار حذف صرف نظر کنید ، همین مثال را به روش Data Annotations نیز می توانید انجام دهید . در این روش کار تعریف کلیدها قدری ساده تر است و در کلاس هر جدول ، وضعیت کلید بودن فیلدها تعریف می گردد . در روش Data Annotations امکان تعریف رفتار حذف وجود ندارد .
public class Coach
{
[Key, Column(Order = 0)]
public int CoachId { get; set; }
[Key, Column(Order = 1)]
public string SportStyle { get; set; }
public string Name { get; set; }
public ICollection<Child> Children { get; set; }
}
public class Child
{
[Key]
public int ChildId { get; set; }
public string Name { get; set; }
public int CoachId { get; set; }
public string SportStyle { get; set; }
[ForeignKey("CoachId, SportStyle")]
public Coach Coach { get; set; }
}
در اینجا، از Data Annotations استفاده میکنیم تا کلید ترکیبی برای موجودیت Coach و کلید داخلی برای موجودیت Child را تعریف کنیم:
[Key, Column(Order = 0)]و[Key, Column(Order = 1)]برای تعریف کلید ترکیبی در موجودیتCoachاستفاده میشوند.[ForeignKey("CoachId, SportStyle")]در موجودیتChildبرای تعریف کلید خارجی که بهCoachارجاع میدهد، استفاده میشود.
در فایل DbContext نیازی به تعریف روابط با استفاده از Fluent API نداریم، زیرا روابط با استفاده از Data Annotations قبلاً تعریف شدهاند:
public class MyDbContext : DbContext
{
public DbSet<Coach> Coaches { get; set; }
public DbSet<Child> Children { get; set; }
}
استفاده از کلید ترکیبی ، پیچیده ترین حالت تعریف یک جدول به حساب می آید که در این مثال ها از کلید ترکیبی استفاده شده بود . اگر مایل باشید جدول شما یک کلید واحد داشته باشد ، نتیجه مطابق کد زیر خواهد بود :
public class Coach
{
[Key]
public int CoachId { get; set; }
public string Name { get; set; }
public ICollection<Child> Children { get; set; }
}
public class Child
{
[Key]
public int ChildId { get; set; }
public string Name { get; set; }
public int CoachId { get; set; }
[ForeignKey("CoachId")]
public Coach Coach { get; set; }
}
در اینجا، از Data Annotations استفاده میکنیم تا کلید داخلی (Primary Key) و کلید خارجی (Foreign Key) برای هر موجودیت تعریف شود:
[Key]برای تعریف کلید داخلی (Primary Key) برایCoachوChildاستفاده شده است.[ForeignKey("CoachId")]در موجودیتChildبرای تعریف کلید خارجی که بهCoachارجاع میدهد، استفاده میشود.
در فایل DbContext نیازی به تعریف روابط با استفاده از Fluent API نداریم، زیرا روابط با استفاده از Data Annotations قبلاً تعریف شدهاند:
public class MyDbContext : DbContext
{
public DbSet<Coach> Coaches { get; set; }
public DbSet<Child> Children { get; set; }
}
منبع : Microsoft Copilot