TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 550 subscribers
Post #584 531
یک نکته‌ی ظریف در EF Core که می‌تونه برنامه‌تون رو کرش بده ⚠️

اگه با EF Core کار کرده باشید، احتمالاً خیلی وقت‌ها برای کلید اصلی این مدلو انتخاب کردید:
builder.Property(x => x.Id)
.ValueGeneratedOnAdd();

یعنی مقدار Id توسط دیتابیس (مثلاً SQL Server با IDENTITY) ساخته می‌شه.

تا اینجا همه‌چیز کاملاً استاندارده.
اما اینجا یه دام خیلی ظریف وجود داره 👇

سناریوی مشکل‌دار 🧨

فرض کنید در Domain Layer اومدید برای Id یک ولیدیشن گذاشتید:
public class Order
{
public int Id { get; private set; }

public Order()
{
if (Id <= 0)
throw new DomainException("Id must be positive");
}
}

یا حتی در setter:
set
{
if (value <= 0)
throw new DomainException();
_id = value;
}

در ظاهر کاملاً منطقیه:
«شناسه نباید منفی یا صفر باشه» ✅

ولی برنامه‌تون موقع ()SaveChanges کرش می‌کنه! 💥

دلیل واقعی چیـه؟ (رفتار داخلی EF) 🧠

ءEF Core وقتی یک entity جدید رو Add می‌کنه، هنوز هیچ Id واقعی‌ای نداره.
اما برای اینکه بتونه Change Tracking و Relationship ها رو مدیریت کنه، مجبور می‌شه:
"یک Temporary Key براش بسازه."
و این کلید موقت معمولاً:
• عدد منفیه
• فقط داخل حافظه است
• هرگز وارد دیتابیس نمی‌شه

مثلاً:
Order.Id = -2147482647


✨️ءEF از این مقدار استفاده می‌کنه تا:

• ءFKها رو ست کنه
• ءGraph از entityها رو track کنه
• بعد از Insert، مقدار واقعی رو جایگزین کنه

پس چرا برنامه کرش می‌کنه؟ 💣

چون شما در Domain گفتید:
«ءId منفی غیرقانونیه»

ولی EF می‌گه:
«من مجبورم موقتاً منفی بذارم»

و این دو تا با هم invariant همدیگه رو می‌شکنن.

💡نتیجه:

EF مقدار منفی ست می‌کنه →
Domain validation تریگر می‌شه →
Exception →
Crash 😬

این دقیقاً چه درسی به ما می‌ده؟ 🎯

این یه مثال عالیه از این اصل مهم در DDD:

ءDomain نباید به مکانیزم‌های زیرساختی وابسته باشه

و مهم‌تر:
ءId دیتابیس نباید identity دامنه باشد

راه‌حل‌های درست (Professional Approaches) 🧩

1️⃣ اصلاً روی Id دیتابیس ولیدیشن نذار 🚫

بهترین و رایج‌ترین راه:
// No validation on Id at all
public int Id { get; private set; }

چون:
ءDomain نباید به persistence concern حساس باشه
ءId دیتابیس یک detail فنیه، نه business rule

2️⃣ از Surrogate Key در دامنه استفاده نکن 🔑

به جای این:
Order.Id (int identity)

از identityهایی استفاده کن که در Domain تولید می‌شوند
(Guid/Ulid/ValueObject)

یعنی:
ءId دامنه = چیزی که خودت می‌سازی
ءId دیتابیس = فقط برای storage

3️⃣ اگر خیلی وسواسی هستی: Validation رو بعد از Persist انجام بده

مثلاً:
public bool IsPersisted => Id > 0;

ولی این عملاً یعنی پذیرفتی که:
ءId قبل از persistence معتبر نیست
که باز هم یعنی validation روش منطقی نیست.

نکته‌ی خیلی عمیق معماری 🧠🔥

این مشکل یه نمونه‌ی کلاسیک از تضاد بین این دو دنیاست:
Domain World ORM World
Invariants Temporary keys
Business meaning Technical identity
Stability Internal mutations

و دقیقاً نشون می‌ده چرا:
نباید مفاهیم دیتابیس رو مستقیم وارد دامنه کنیم

جمع‌بندی طلایی 🏆

اگر از ValueGeneratedOnAdd یا IDENTITY استفاده می‌کنید:

❌ هرگز روی Id در دامنه validation نگذارید
❌ هرگز Id دیتابیس رو business concept در نظر نگیرید

در عوض:

✅ دامنه = با مفاهیم بیزینسی (Value Objects)
✅ دیتابیس = فقط ابزار ذخیره‌سازی

و این جمله رو همیشه یادت باشه:

ءTemporary keys در EF یک persistence concern هستند،
و نباید وارد invariants دامنه شوند.

این دقیقاً همون جاییه که مهندسی نرم‌افزار از «کدنویسی» جدا می‌شه 🚀

🔖هشتگ‌ها:
#EFCore #DDD #CleanArchitecture #ORM #DomainModel #SoftwareEngineering #DotNet
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →