Domain-Driven Design (DDD)؛ بخش یازدهم: DDD با EF Core؛ قسمت سوم
نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۶/۰۶ ۰۸:۰۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
// Customer is an Aggregate Root
public class Customer
{
public int CustomerId { get; private set; }
// ...
}
// Order is another Aggregate Root
public class Order
{
public int OrderId { get; private set; }
public int CustomerId { get; private set; }
// ...
}public class Student
{
public int StudentId { get; private set; }
private readonly List<Class> _classes = new List<Class>();
public IReadOnlyList<Class> Classes => _classes.AsReadOnly();
public void EnrollInClass(Class newClass)
{
_classes.Add(newClass);
}
}
public class Class
{
public int ClassId { get; private set; }
private readonly List<Student> _students = new List<Student>();
public IReadOnlyList<Student> Students => _students.AsReadOnly();
}Student و Class فقط به یکدیگر ارجاع میدهند. EF Core به اندازه کافی هوشمند است که با دیدن این دو کلکسیون، به صورت خودکار یک جدول واسط در دیتابیس ایجاد کند. شما نیازی به ساخت کلاس واسط ندارید.enum را با مشخصهی [Flags] تعریف کرد:[Flags]
public enum ColorEnum
{
None = 0,
Green = 1,
Blue = 2,
Red = 4
}public class Product
{
public int Id { get; private set; }
public ColorEnum SelectedColors { get; private set; }
private Product() { } // برای EF-Core
public Product(ColorEnum selectedColors)
{
SelectedColors = selectedColors;
}
public void AddColor(ColorEnum color)
{
SelectedColors |= color;
}
public void RemoveColor(ColorEnum color)
{
SelectedColors &= ~color;
}
public bool HasColor(ColorEnum color) => SelectedColors.HasFlag(color);
}int یا bigint).public class SelectedColor
{
public ColorEnum Color { get; private set; }
private SelectedColor() { }
public SelectedColor(ColorEnum color) => Color = color;
}public class Product
{
private readonly List<SelectedColor> _selectedColors = new();
public IReadOnlyCollection<SelectedColor> SelectedColors => _selectedColors;
public void AddColor(ColorEnum color)
{
if (_selectedColors.Any(c => c.Color == color))
return;
_selectedColors.Add(new SelectedColor(color));
}
public void RemoveColor(ColorEnum color)
{
var item = _selectedColors.FirstOrDefault(c => c.Color == color);
if (item != null)
_selectedColors.Remove(item);
}
}public class Product
{
public int Id { get; private set; }
public List<ColorEnum> SelectedColors { get; private set; } = new();
}modelBuilder.Entity<Product>()
.Property(p => p.SelectedColors)
.HasConversion(
v => string.Join(",", v), // ذخیره در DB
v => v.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(e => Enum.Parse<ColorEnum>(e))
.ToList()
);Flag Enum بهترین گزینه است.ValueConverter روی یک string یا json.int، string و حتی enum را با EF-Core نگاشت کرد و در پایگاه داده به صورت ستون JSON، ذخیرهشده داشت. این قابلیت با پشتیبانی پایگاهدادههای مدرن از JSON همراه است.IReadOnlyList، IReadOnlyCollection یا ReadOnlyCollection نیز میشود، که برای سناریوهایی که شامل مجموعههای تغییرناپذیر هستند بسیار مناسب است.public List<ColorEnum> SelectedColors { get; set; } = new();IReadOnlyCollection یا دیگر انواع خواندنی در EF Core 9 وجود دارد.| سناریو | رویکرد پیشنهادی | مناسب برای... |
| فقط پرچم ساده | Flag Enum | وقتی تنها نیاز به ذخیره چند گزینه هست |
| منطق و متادیتا | Value Object Collection | وقتی قوانین دامنه و توسعهپذیری اهمیت دارد |
| نگهداری سبک، بدون جدول اضافی | Primitive Collections (JSON) | وقتی میخواهید ساده نگه دارید و Query ساده نیاز دارید |