مسیر C#/.NET و آداپتورهای پشته · فصل ۱ — Modern C#، ASP.NET Core، EF Core و Testing · 327

EF Core Data Access و Migrations

دانش قدیمی یا پراکنده‌ی .NET دارد اما آن را با الگوهای مدرن API/data/testing/hosting همگام نکرده است. موضوع جاری: «EF Core Data Access و Migrations». می‌تواند «EF Core Data Access و Migrations» را در یک سرویس .NET محدود اجرا و با تست/diagnostics مناسب verify کند.

EF Core Data Access and Migrations — en-US

خلاصهٔ درس

دانش قدیمی یا پراکنده‌ی .NET دارد اما آن را با الگوهای مدرن API/data/testing/hosting همگام نکرده است. موضوع جاری: «EF Core Data Access و Migrations».

می‌تواند «EF Core Data Access و Migrations» را در یک سرویس .NET محدود اجرا و با تست/diagnostics مناسب verify کند.

خروجی این درس

می‌تواند «EF Core Data Access و Migrations» را در یک سرویس .NET محدود اجرا و با تست/diagnostics مناسب verify کند.

پیش‌نیازها

migration اجرا شد؛ نام خریدارها چه شد؟

جدول سفارش‌ها دو سفارش ارسال‌نشده دارد: ندا و رضا. مدل تازه نام CustomerName را به BuyerName تغییر می‌دهد، فیلد اجباری Status اضافه می‌کند و برای تشخیص تعارض، توکن هم‌زمانی می‌خواهد. هوش مصنوعی migration را می‌نویسد: ستون قدیمی حذف می‌شود و ستون تازه ساخته می‌شود. فرمان بدون خطا تمام می‌شود. آیا نام خریدارها حفظ شده است؟

خروجی شما EF Core Data Access, Migration and Concurrency Evidence Ledger v1 است: دفتر شواهدی که مدل، ارائه‌دهندهٔ پایگاه داده، رفتار خواندن، عملیات migration، مشاهدهٔ داده و تصمیم تعارض را به هم وصل می‌کند. با آن می‌توانید نشان دهید کدام بخش آمادهٔ بازبینی است و برای کدام بخش هنوز شاهد کافی ندارید.

۶۰ دقیقه زمان فعال در نظر بگیرید: ۱۰ دقیقه مدل ذهنی، ۱۵ دقیقه مثال، ۱۵ دقیقه تمرین هدایت‌شده، ۱۵ دقیقه انتقال مستقل و ۵ دقیقه دفاع از تصمیم. تمرین اصلی با Python 3.10 یا جدیدتر و JSON مصنوعی اجرا می‌شود؛ کتابخانهٔ بیرونی، سرور پایگاه داده یا SDK لازم ندارد. یک برنامهٔ دوم واقعاً SQL را روی دادهٔ موقت SQLite اجرا می‌کند. این اجرا، اجرای EF Core نیست. قطعه‌کدهای C# برای فهم APIها هستند و پروژهٔ کامپایل‌شده یا رسید اجرای تهیه‌کننده محسوب نمی‌شوند.

برای کسی که مبانی C#، فراخوانی ناهم‌زمان و طول عمر وابستگی‌ها را می‌شناسد و می‌خواهد تغییر دسترسی به داده را با شواهد توجیه کند.

ساخت API کامل، انتخاب پایگاه دادهٔ تولید، اجرای migration روی دادهٔ واقعی و تکمیل تست، عیب‌یابی و میزبانی NET-004 در محدودهٔ این درس نیست.

پیش‌نیاز را بسنجید و مسیر ورود را انتخاب کنید

NET-001 پیش‌نیاز ضروری و آشنایی با NET-002 کمک‌کننده است. ترتیب آموزشی از NET-002 به این درس و سپس NET-004 می‌رود؛ ترتیب تولید فایل‌ها این رابطه را تغییر نمی‌دهد.

توضیح دهید await منتظر چه چیزی می‌ماند، چه کسی وابستگی scoped را آزاد می‌کند و چرا دو عملیات هم‌زمان نباید یک واحد کارِ تغییرپذیر را مشترک استفاده کنند. سپس تفاوت property در C# و ستون ذخیره‌شده در پایگاه داده را بگویید.

مدل می‌گوید برنامه چه ساختاری انتظار دارد؛ پایگاه داده مقدارها را طبق ساختار موجود نگه می‌دارد. تغییر یکی، دیگری را خودکار تغییر نمی‌دهد. واحد کار تغییرهای مرتبط را جمع می‌کند و مالک آن باید کار را تمام و منابعش را آزاد کند. پیش از استفادهٔ دوباره از context، پایان عملیات قبلی را await کنید. برای عبور از این پل، توضیح دهید چرا عوض‌شدن نام property ممکن است ستون قبلی را دست‌نخورده بگذارد و چه چیزی مالک تغییرهای ذخیره‌نشده است.

در مسیر پایه، نگاشت فیلدها و هر دو مثال را بخوانید. در مسیر رفع اشکال، نخستین بُعد نامعتبر را جدا کنید، اما سایر موانع را تا زمان رفع‌شدن نگه دارید. اگر باتجربه‌اید، مبادله‌های طراحی را بخوانید و از تمرین مستقل شروع کنید. خروجی، مثال منفی و انتقال زمینه در هر سه مسیر یکسان است.

پنج سند، پنج پرسش متفاوت

مدل ساختار مورد انتظار برنامه است. snapshot مدل ساختار ثبت‌شده هنگام آخرین ساخت migration را نشان می‌دهد. عملیات migration پیشنهاد تغییر ساختار است. تاریخچهٔ migration در پایگاه داده می‌گوید کدام migrationها اعمال شده‌اند. ردیف‌های مشاهده‌شده و تست‌ها نشان می‌دهند در یک محیط مشخص واقعاً چه نتیجه‌ای به دست آمده است. توافق دو سند به‌تنهایی کافی نیست.

EF از تغییر مدل برای ساخت تغییرهای تدریجی ساختار استفاده می‌کند و تاریخچهٔ اعمال آن‌ها را نگه می‌دارد. ابزار ممکن است تغییر نام را حذف و افزودن تشخیص دهد؛ عملیات تولیدشده باید بازبینی شوند. معرفی migrations، مدیریت migrations

فرض کنید همهٔ فایل‌های migration روی پایگاه داده اعمال شده‌اند، ولی برنامه‌نویس بعداً Archived را به مدل اضافه کرده و migration تازه نساخته است. migration اعمال‌نشده‌ای وجود ندارد، اما مدل هنوز با snapshot متفاوت است. برعکس، ممکن است مدل تغییر نکرده باشد ولی پایگاه داده یکی از migrationهای موجود را نداشته باشد. علت و تعمیر این دو وضعیت یکی نیست.

معادل متنی نمودار چنین است: مدل و provider را مشخص کنید؛ خواندن و tracking را بسنجید؛ snapshot، عملیات و تاریخچه را مقایسه کنید؛ تست یک‌بارمصرف را اجرا کنید؛ تعارض را حل کنید؛ شواهد برنامهٔ استقرار را بازبینی کنید. شاهد مفقود یا کهنه به HOLD می‌رسد. شاهد منفی به تعمیر و اجرای دوباره نیاز دارد و تا آن زمان HOLD می‌ماند. شواهد کامل فقط در قرارداد مصنوعی این تمرین، READY_FOR_REVIEW می‌دهند. این وضعیت‌ها طراحی آموزشی MAKNOW هستند و مجوز استقرار مایکروسافت نیستند.

پیش از حکم نهایی، دفتر شواهد را بخوانید

پرسشفیلدهای مرتبطمعنای فقدان شاهد
کدام بخش دسترسی به داده؟dbcontext_id، provider_id، fixture_database_ref و revisionهویت یا دامنه تأیید نشده است
کدام رفتار خواندن؟query_id، tracking_mode، projection_shape و ردیف‌هاقرارداد query تأیید نشده است
کدام گذار ساختار؟migration_id، model_snapshot_ref، وضعیت pending، تاریخچه و عملیاتنقطهٔ شروع یا گذار پیشنهادی نامعلوم است
آیا نویسندهٔ قدیمی بازنویسی می‌کند؟توکن، تعداد ردیف تغییریافته، تعارض و حل آنرفتار هم‌زمانی تأیید نشده است
چه کسی برنامه را بازبینی می‌کند؟راهبرد، توضیح قفل، مالک، capture و audit_event_idهنوز تصمیم محدود قابل دفاع نیست

فایل قابل دریافت NET-003-T1.csv همهٔ فیلدهای شواهد را دارد؛ جدول بالا راهنمای خواندن است. ساختار JSON تو‌در‌تو است. برای مثال، مقدار migration_operation دفتر از /migration/operations می‌آید و شاهد مستقلی اختراع نمی‌کند. نگاشت کامل در field_map.json آمده است.

UNKNOWN یعنی مقدار تعیین‌کننده نامعلوم است؛ UNVERIFIED یعنی شاهد آن را ثابت نکرده؛ UNSUPPORTED یعنی provider یا قرارداد از ادعا پشتیبانی نمی‌کند؛ STALE یعنی شاهد دیگر متعلق به زمان یا زمینهٔ فعلی نیست. FAILED نقض انتظار و REVIEW_REQUIRED نیاز به بازبینی را ثبت می‌کنند. چند تست موفق هیچ‌کدام را خنثی نمی‌کنند. CONCURRENCY_CONFLICT تا زمان وجود راه‌حل کسب‌وکاریِ آزموده‌شده آشکار می‌ماند. حل تعارض با ردِ نوشتن می‌تواند نتیجهٔ موفق تست منفی باشد، چون انتظار همین ردشدن بوده است.

در این تمرین تمام سفارش‌های اولیه ارسال‌نشده‌اند؛ فقط همین فرض کسب‌وکاری اجازه می‌دهد مقدار گذشتهٔ Status را Pending بگذاریم. این مقدار برای جدول تاریخیِ شامل سفارش‌های تکمیل‌شده لزوماً درست نیست. مقدار اولیهٔ توکن، ۱ است و معنای زمان ثبت ندارد.

از کد EF به شاهد قابل بررسی

EF Core 10 به .NET 10 نیاز دارد و نسخهٔ LTS آن تا ۱۰ نوامبر ۲۰۲۸ پشتیبانی می‌شود. پشتیبانی نسخه، سازگاری provider با برنامهٔ شما را اثبات نمی‌کند. EF Core 10

مرز context و query

DbContext را برای یک واحد کار کوتاه نگه دارید. این شیء برای استفادهٔ هم‌زمان thread-safe نیست؛ عملیات را await کنید یا برای کارهای مستقلِ هم‌زمان context جدا داشته باشید. طول عمر DbContext

قرارداد خواندن entity در مثال ما روشن است:

var orders = await db.Orders.AsNoTracking()
    .OrderBy(o => o.Id).ToListAsync(cancellationToken);

entityها در change tracker این context نگه داشته نمی‌شوند. query دارای tracking ممکن است نمونهٔ از قبل رهگیری‌شده را بازگرداند. projection فقط از مقدارهای scalar به DTO، entity قابل رهگیری ندارد؛ ولی خروجی ناشناسِ حاوی entity همچنان می‌تواند آن entity را رهگیری کند. پس «هر projection بدون tracking است» یا «بدون tracking همیشه سریع‌تر است» قاعدهٔ عمومی درستی نیست. Tracking

تست ما با context تازه شروع می‌شود و دو entity و صفر ورودی رهگیری‌شده انتظار دارد. حذف AsNoTracking ممکن است مقدارهای خروجی را عوض نکند، ولی قرارداد tracking را بشکند. تستی که فقط تعداد ردیف‌ها را می‌سنجد این تغییر را نمی‌بیند. از برنامهٔ SQL این درس نیز نمی‌توان رفتار change tracker در EF را نتیجه گرفت.

گذار را بازبینی کنید، نه فقط نام فایل را

فرمان‌های زیر برای پروژهٔ جداگانه و یک‌بارمصرف EF Core 10 با provider و ابزار متناظر هستند؛ در پوشهٔ Python هنرجو اجرا نمی‌شوند:

dotnet ef migrations add BuyerStatusVersion
dotnet ef migrations has-pending-model-changes
dotnet ef migrations script Initial BuyerStatusVersion

برای بازهٔ script، نام یا شناسهٔ واقعی migrationهای همان پروژه را قرار دهید. شناسه‌های JSON ما، 001_Initial و 002_BuyerStatusVersion، برچسب مصنوعی‌اند و شناسهٔ timestampدار تولیدشده نیستند. پیش از اعمال script، عملیات Up را بررسی کنید. هدف تغییر نام چنین است:

migrationBuilder.RenameColumn(
    name: "CustomerName", table: "Orders", newName: "BuyerName");

سپس فیلدهای اجباری را مطابق فرض کسب‌وکاری اضافه و دادهٔ قبلی را مقداردهی کنید. SQL تولیدشده برای همان provider را بخوانید و روی ردیف‌های یک‌بارمصرف بیازمایید. نام‌ها و تعداد ردیف قبل و بعد را مقایسه کنید و شکست در میانهٔ گذار را نیز تست کنید. برگشت‌پذیری ساختار، مقدارهایی را که حذف شده‌اند برنمی‌گرداند.

GetPendingMigrationsAsync دربارهٔ migrationهای اعمال‌نشده است و تغییر مدلِ بدون migration را تشخیص نمی‌دهد. برای دومی بررسی pending-model-change لازم است. EF 9 و جدیدتر در مسیر اعمال migration تغییرهای معوق مدل را تشخیص می‌دهند؛ نادیده‌گرفتن هشدار، تعمیر نیست. مدیریت migrations، تغییر رفتار EF 9

تعارض هم‌زمانی به تصمیم کسب‌وکاری نیاز دارد

توکن مثال از نوع عدد صحیح و تحت مدیریت برنامه است:

modelBuilder.Entity<Order>()
    .Property(o => o.Version).IsConcurrencyToken();
// After loading the tracked row and choosing a valid change:
order.Status = "Paid";
order.Version += 1; // The application advances the token.
await db.SaveChangesAsync(cancellationToken);

IsConcurrencyToken() خودش عدد را افزایش نمی‌دهد. توکن ذخیره‌شده و مقدار اصلی در تشخیص تعارض دخیل‌اند؛ اگر update مورد انتظار هیچ ردیفی را تغییر ندهد، EF می‌تواند DbUpdateConcurrencyException بدهد. rowversion خودکار SQL Server مخصوص همان provider است؛ SQLite به راهبرد دیگری، مانند توکن مدیریت‌شده در برنامه، نیاز دارد. هم‌زمانی

دو نویسنده توکن ۱ را می‌خوانند. اولی Paid و توکن ۲ می‌نویسد. دومی هنوز بر مبنای توکن ۱ می‌خواهد Cancelled بنویسد. قاعدهٔ کسب‌وکاری ما ردکردن است: Paid حفظ می‌شود و فراخواننده برای تصمیم تازه باید دوباره بخواند. retry، merge و reject هرکدام سیاست خود را می‌خواهند. عوض‌کردن توکن مورد انتظار و اجرای دوبارهٔ نیت قدیمی، به‌خودی‌خود حل تعارض نیست.

مرز تراکنش و قفل migration

در provider پشتیبان، یک فراخوانی SaveChanges معمولاً تراکنشی است؛ چند فراخوانی خودکار یک تراکنش کسب‌وکاری نمی‌شوند. آزمایش SQL ما تراکنش صریح و تست rollback دارد؛ محدودیت provider همچنان برقرار است. تراکنش‌ها

migration تولیدشده را پیش از تولید بازبینی و تست کنید. قفل مسیر اعمال migration در EF 9 و جدیدتر اجرای هم‌زمان migrationها را محدود می‌کند؛ ترافیک عادی برنامه را متوقف نمی‌کند و سازگاری تغییر آنلاین ساختار را ثابت نمی‌کند. در script اجراشده با ابزار بیرونی، رفتار ابزار و مرز تراکنش را جداگانه بررسی کنید. اعمال migrations

SQLite برای بعضی تغییرها به بازسازی جدول نیاز دارد و سازوکار عمومی scriptهای idempotent در EF را پشتیبانی نمی‌کند. قفل migration آن پس از شکست فرایند ممکن است نیازمند بازیابی باشد. ابتدا فعال‌بودن اجراکننده و وضعیت باقی‌مانده را مشخص کنید؛ این درس فرمان حذف کورکورانهٔ جدول قفل نمی‌دهد. آزمایش دو ردیف SQLite، migration در SQL Server را تأیید نمی‌کند. محدودیت SQLite، راهبرد تست

مثال حل‌شده: حفظ نام و ردکردن نویسندهٔ قدیمی

fixtures/baseline.json را باز کنید. مشاهده‌های آن مصنوعی و متعلق به orders-r2-sqlite-small هستند. ابتدا انتظار را بخوانید:

بررسیانتظارمشاهدهٔ baselineبرداشت محدود
تغییر نامحفظ Neda و Rezaهر دو مقدار در BuyerName مانده‌اندگذار این نمونه داده را حفظ کرده است
فیلدهای اجباریPending و توکن ۱هر دو ردیف مطابق انتظارندفقط با فرض ارسال‌نشدن سفارش‌ها درست است
خواندن entityدو ردیف و صفر entity رهگیری‌شدههر دو برقرارندقرارداد خواندن رعایت شده است
دو نویسندهاولی ۱ ردیف، دومی ۰ ردیفPaid مانده و REJECT آزموده شدهتعارض مشاهده و با ردکردن حل شده است
شکست میانیحفظ دادهٔ اولیه پس از rollbackهر دو نام اصلی باقی‌اندانتظار بازگشت این نمونه برقرار است

این رکورد کامل، READY_FOR_REVIEW با دامنهٔ SYNTHETIC_ONLY می‌دهد و اجرای واقعی EF را گزارش نمی‌کند. مرحلهٔ migration و query مقدار Pending انتظار دارد؛ بعدتر نویسندهٔ اول آن را Paid می‌کند و تست تعارض حفظ همین مقدار را می‌سنجد. این‌ها زمان‌های متفاوت آزمایش‌اند، نه دو گزارش ناسازگار از یک لحظه.

اکنون drop_add.json را بخوانید. /migration/operations/0 ستون CustomerName را حذف می‌کند. حتی اگر /migration/data_loss_warning برابر false و برچسب تست‌ها PASS باشد، خود عملیات شرط حفظ داده را نقض می‌کند. هم عملیات مخرب و هم فاصله با برنامهٔ بازبینی‌شده را ثبت کنید؛ نتیجه HOLD است. تعمیر حداقلی، بازبینی تغییر نامِ حافظ داده، بازسازی شواهد migration و اجرای دوبارهٔ تست حفظ مقدار و rollback است. false کردن هشدار چیزی را تعمیر نمی‌کند.

برای مشاهدهٔ واقعیِ جداگانه، python sqlite_demo.py را اجرا کنید. برنامه فقط دادهٔ درون‌حافظه‌ای می‌سازد، گذار ساختار و دو update رقیب را اجرا می‌کند و شکست میانی و rollback را می‌آزماید. خروجی JSON شامل ef_core_executed: false است. جدول آموزشی LessonMigrationHistory تاریخچهٔ واقعی EF نیست. صفر ردیف تغییریافته، منطق شرط پایگاه داده را نشان می‌دهد؛ این برنامه exception متعلق به EF را اجرا یا تست نمی‌کند.

برچسب سبز چه چیزی را پنهان می‌کند؟

تغییر منفیفرض شکسته‌شدهشاهد لازم برای ادامه
پذیرفتن حذف/افزودن به‌جای تغییر ناممقدارهای قدیمی حفظ می‌شوندعملیات بازبینی‌شده و ردیف‌های قبل/بعد
تغییر مدل پس از ساخت migrationsnapshot نیت فعلی را بیان می‌کندمقایسهٔ مدل و migration بازبینی‌شده
rowversion مخصوص SQL Server در SQLiteراهبرد توکن پشتیبانی می‌شودراهبرد سازگار و تست تعارض تازه
شروع tracking در query خواندنیمقدار یکسان یعنی رفتار یکسانمشاهدهٔ tracking در context تازه
capture خالی با PASSبرچسب نتیجه شاهد اجراستمشاهدهٔ دارای ارجاع و زمینهٔ درست

حالت‌های missing_evidence، history_gap و stale_review تمرین تکمیلی‌اند. بگویید چه چیزی مفقود یا نامعتبر است؛ capture تازه اختراع نکنید. لینک مستندات یک API را توضیح می‌دهد و جای نتیجهٔ اجرای شما را نمی‌گیرد. نام بازبین داخل fixture مصنوعی نیز مجوز مالک واقعی تولید نیست.

رفع یک علت، سایر موانع را از بین نمی‌برد. مجموعهٔ کامل علت‌ها را نگه دارید، بُعد آسیب‌دیده را با کوچک‌ترین تعمیر منسجم اصلاح کنید و دوباره محاسبه کنید. اگر تغییر جدید قرارداد ثابت تمرین را عوض می‌کند، قرارداد تازهٔ بازبینی‌شده لازم است؛ انتظار را پنهانی با نتیجهٔ موجود همسان نکنید.

مسیر افراد باتجربه: ابتدا فرض‌ها را پیدا کنید

آیا entity از قبل رهگیری‌شده می‌تواند خواندن را تغییر دهد؟ آیا مقداردهی ستون اجباری حقیقت دادهٔ قدیمی را حفظ می‌کند؟ آیا retry همان تصمیم کسب‌وکاری را تکرار می‌کند که اکنون دیگر معتبر نیست؟ پاسخ این پرسش‌ها از حفظ‌کردن فرمان‌ها بیشتر دربارهٔ درستی طراحی می‌گوید.

فایل SQL تولیدشده باید از نظر وضعیت مقصد، حفظ داده، مرز تراکنش، سازگاری برنامه هنگام تغییر، قفل مورد انتظار و بازیابی بررسی شود. REVIEWED_MANUAL_SCRIPT راهبرد کنترل‌شدهٔ این نمونه است و به این معنا نیست که همهٔ برنامه‌ها باید اجرای دستی داشته باشند. روش دیگری هم انتخاب کنید، تعهد شواهد باقی می‌ماند.

تجربهٔ قبلی را با دامنهٔ درست منتقل کنید. query موفق در SQLite رفتار ترجمه، قفل یا rowversion در SQL Server را ثابت نمی‌کند. provider درون‌حافظه‌ای EF هم صحت migration رابطه‌ای را نشان نمی‌دهد. مسیر سریع از زمان خواندن توضیح‌ها کم می‌کند؛ تست منفی و انتقال زمینه را حذف نمی‌کند.

راهبرد را با تعهدهای باقی‌مانده انتخاب کنید

انتخابچه چیزی را کمک می‌کند؟چه شاهدی هنوز لازم است؟
تغییر نام ستون موجودحفظ پیوستگی مقدار قبلیSQL تولیدشده، سازگاری برنامه و آزمایش
افزودن، مقداردهی، تغییر مصرف و حذف دیرترمرحله‌بندی گذار بزرگ‌تردرستی backfill، نسخه‌های هم‌زمان، قفل و پاک‌سازی
توکن مدیریت‌شده در برنامهتغییر صریح توکن در providerهای مختلفافزایش توکن در تمام نوشتن‌های مرتبط و تست حل تعارض
rowversion در SQL Serverتوکن تحت مدیریت پایگاه دادهنگاشت، سیاست تعارض و تست مخصوص provider
script بازبینی‌شده یا migration bundleخروجی کنترل‌شدهٔ استقراروضعیت مقصد، رفتار اجراکننده، بازیابی و بازبینی مالک

برای جدول بزرگ، سازگاری مرحله‌ای و batchهای اندازه‌گیری‌شده را بررسی کنید؛ مناسب‌بودن عملیات نمونهٔ کوچک را تعمیم ندهید. قاعدهٔ تمرین از ۱۰۰٬۰۰۰ ردیف به بالا آزمایش دسته‌ای می‌خواهد. این عدد آستانهٔ آموزشی است و حد امن عمومی پایگاه داده نیست. در واقعیت ساختار، بار، سخت‌افزار و وقفهٔ قابل قبول دخیل‌اند. پنج میلیون ردیف با capture نمونهٔ کوچک این شرط را برآورده نمی‌کند.

پاسخ خودتان را بسازید و ورودی را حفظ کنید

فایل‌های هنرجو را دریافت و باز کنید. ترمینال را در پوشهٔ learner قرار دهید. با فهرست ورودی‌ها و آزمایش اختیاری SQL شروع کنید:

python run_checks.py --inventory
python sqlite_demo.py
python run_checks.py --template fixtures/pending_model.json submission.json --as-of 2026-09-12

قالب، هش ورودی و policy، زمینه و تاریخ ارزیابی را می‌گذارد؛ تصمیم و استدلال را خودتان می‌نویسید. فایل خروجی موجود بازنویسی نمی‌شود. تاریخ تاریخی بالا مقایسهٔ موعد بازبینی این نسخه را تکرارپذیر می‌کند. برای ارزیابی فعلی تاریخ امروز را ثبت کنید؛ تاریخ‌گذاری گذشته نباید انقضای شاهد را پنهان کند.

تمرین هدایت‌شده: شکل مدل هدف را با snapshot و قرارداد ثابت مقایسه کنید. قاعدهٔ MODEL_PENDING را در policy.json دنبال کنید و pointer دقیقِ باطل‌کنندهٔ ادعای NONE را پیدا کنید. وضعیت کلی، تمام علت‌ها با code و state و فیلدهای evidence_refs، rationale، minimal_repair و review_trigger را پر کنید. توضیح دهید تغییر مورد نظر چگونه migration بازبینی‌شده می‌گیرد؛ ورودی اصلی را برای ساخت PASS ویرایش نکنید.

python run_checks.py --check fixtures/pending_model.json submission.json

STRUCTURE_PASS_SEMANTICS_UNREVIEWED فقط می‌گوید پاسخ ساختار درست دارد و به همین ورودی متصل است؛ درستی تصمیم را تأیید نمی‌کند. ارجاع‌ها JSON Pointer هستند؛ مانند /model/target که فیلد همین fixture را نشان می‌دهد. برای آرایه شاخص عددی و در صورت نیاز escapeهای معتبر ~0 و ~1 به کار ببرید.

سپس tracking_changed، unsupported_token و concurrency_conflict را مستقل تحلیل کنید. در پایان برای transfer_provider.json پاسخ تازه بسازید: مقصد SQL Server با پنج میلیون ردیف هنوز شاهدهای زمینهٔ قبلی را حمل می‌کند. همهٔ بُعدهای آسیب‌دیده، تصمیم محدود و کمینهٔ آزمایش تازهٔ مخصوص provider را مشخص کنید. پاسخ انتقال از پیش پر نشده است. همهٔ captureها را مصنوعی بدانید و بگویید پیش از بازبینی استقرار چه مشاهدهٔ واقعی لازم خواهد بود.

هوش مصنوعی می‌تواند شواهد داده‌شده را مرتب یا استدلال را نقد کند. ساختن نتیجهٔ تست، جایگزین‌کردن مجوز مفقود و اختراع تأیید مالک مجاز نیست. خوانندهٔ دیگری باید بتواند توضیح نهایی شما را بررسی کند.

خروجی تحویلی چه چیزی را ثابت می‌کند؟

هویت و SHA-256 ورودیِ دست‌نخورده، هش policy، زمینه، تاریخ ارزیابی، وضعیت کلی، مجموعهٔ کامل علت‌ها و نوع وضعیت، ارجاع دقیق فیلدها، استدلال، تعمیر حداقلی و محرک بازبینی را تحویل دهید. دفتر baseline، تشخیص تغییر مخرب و پاسخ مستقلِ provider جدید را ضمیمه کنید. جدول‌های CSV و JSON دو نمایش هماهنگِ مثال حل‌شده‌اند و پاسخ آمادهٔ تمرین مستقل نیستند.

بررسی عمومی فقط ساختار و اتصال را می‌سنجد. بررسی معنایی مدرس، وضعیت و مجموعهٔ کامل علت‌ها را با قواعد قابل مشاهده مقایسه می‌کند و هنوز به بازبینی توضیح و ارجاع‌ها نیاز دارد. هیچ‌کدام هش را مدرک اجرای واقعی یک capture مصنوعی نمی‌دانند. بازبین انسانی باید از همین فایل‌های قابل مشاهده نتیجه را بازسازی کند.

برای شاهد اجرای واقعی، revision پروژه، نسخهٔ SDK و EF/provider، هویت پایگاه داده، فرمان‌ها، منبع migration و SQL، مشاهده‌ها، شکست‌ها و پاک‌سازی را هم ثبت کنید. شاهد منفی اولیه پس از تعمیر حفظ شود. رسید تهیه‌کننده در این نسخه فقط اجرای واقعی SQL روی ردیف‌های ساختگی SQLite را پوشش می‌دهد؛ tracking، scaffolding، exceptionهای EF و رفتار SQL Server اجرا نشده‌اند.

چهار تکلیف و پنج معیار بحرانی

NET-003-S1 — بازیابی. تفاوت snapshot مدل، تاریخچهٔ migration و ردیف مشاهده‌شده را توضیح دهید. مرز دسترسی به دادهٔ این درس و یک خروجی متعلق به درس مجاور را نام ببرید.

NET-003-S2 — کاربرد. دفتر شواهد baseline را بسازید و وضعیت محدود آن را توجیه کنید. چرا ردشدن نوشتن قدیمی می‌تواند تست هم‌زمانی را موفق کند و چرا مجوز تولید نمی‌دهد؟

NET-003-S3 — تشخیص. در تغییر حذف/افزودن، عملیات نامعتبر، پیامد احتمالی برای داده و کمینهٔ تعمیر حافظ داده را مشخص کنید. چرا PASS و false بودن هشدار نمی‌توانند خود عملیات را بی‌اثر کنند؟

NET-003-S4 — انتقال. تصمیم transfer_provider را از شواهد خودش بسازید. provider و مقیاس تازه، همهٔ captureهای نیازمند جایگزینی، برنامهٔ آزمایش مناسب و شرط بازشدن دوبارهٔ بازبینی را بنویسید. حکم baseline را کپی نکنید.

پنج معیار عبارت‌اند از مرز و قرارداد، اتصال دقیق شواهد، شاهد منفی، تصمیم محدود و انتقال. هر پنج باید کافی باشند؛ میانگین‌گیری شکست بحرانی را نمی‌پوشاند. وضعیت کلی درست با علت‌های ناقص کافی نیست؛ فهرست کامل بدون توضیح پیامد داده نیز کافی نیست. برای خطای مرز به مدل ذهنی، برای tracking یا توکن به توضیح فنی و برای انتقال کپی‌شده به ساخت دوبارهٔ دفتر زمینهٔ جدید برگردید.

منابع، تاریخ و مرز ادعا

صفحه‌های رسمی مایکروسافت در 2026-09-12 بررسی شدند. بازبینی بعدی برای 2026-10-18 است؛ تغییر مرتبط EF یا provider این موعد را جلو می‌اندازد. فهرست کامل منابع در sources.json و source_links.md بستهٔ هنرجو موجود است. معرفی migrations و مستند هم‌زمانی مرز اصلی رفتار پلتفرم را توضیح می‌دهند.

FACT رفتار مستند API یا provider است؛ INFERENCE نتیجه‌ای است که شواهد اجازه می‌دهند؛ DESIGN قرارداد دو ردیفی، سیاست ردکردن، وضعیت‌های آموزشی و آستانهٔ جدول بزرگ است. مستندات مایکروسافت دستهٔ اول را پشتیبانی می‌کنند و جای مدرک اجرای مفقود یا تأیید تمرین MAKNOW را نمی‌گیرند. برای تازه‌سازی، نسخهٔ جدیدِ بازبینی‌شده بسازید؛ منبع، هش fixture و مشاهدهٔ تاریخ‌دار این نسخه را حفظ کنید.

ارزیابی

پاسخ‌نامه‌ی این درس در بسته‌ی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار می‌فرستد.

ملاک‌های ارزیابی (rubric)

هر پنج معیار باید کافی باشند؛ میانگین جای شرط بحرانی را نمی‌گیرد. Every critical dimension must be sufficient.

معیار / Dimensionکافی / Sufficientناکافی / Insufficient
مرز / Scopeمرز مدل، migration، مشاهده و استقرار / Distinguishes model, migration, observation and deploymentاجرای مصنوعی را مجوز تولید می‌داند / Treats synthetic evidence as deployment permission
اتصال / Bindingهویت، هش، زمینه، تاریخ و pointer دقیق / Exact identity, hash, context, date and pointerscapture قدیمی یا ارجاع نامعتبر / Stale capture or invalid reference
منفی / Negative evidenceتمام علت‌ها، پیامد داده و نوع وضعیت / Every blocker, data consequence and typed stateفقط حکم کلی یا حذف تعارض / Aggregate only or suppressed conflict
تصمیم / Decisionدامنه، تعمیر حداقلی و محرک بازبینی / Scope, minimal repair and review triggerretry کور یا PASS بی‌شاهد / Blind retry or unsupported PASS
انتقال / Transferبازسازی شواهد provider و جدول بزرگ / Rebuilds provider and large-table evidenceکپی baseline / Copies baseline

Python و SQLite اجرای EF نیستند. Python/SQLite success does not establish EF execution. Review explanations, not only machine output.

منابع و تازگی

· TOOL_VOLATILE
Microsoft EF Core 10 release and support boundary.
· TOOL_VOLATILE
Microsoft EF Core migrations overview for incremental schema evolution and migration history.
· TOOL_VOLATILE
Microsoft guidance for migration deployment, review, locking and pending-model-change behavior.
· PRACTICE_EVOLVING
Microsoft guidance for optimistic concurrency tokens and conflict handling in EF Core.
·
Rename review, scaffolding and pending-model changes
·
Entity tracking and scalar-only projections
·
SQLite rebuild, script and migration-lock limitations
·
Context lifetime and concurrency
·
Pending-model-change application behavior
·
SaveChanges and explicit transaction boundaries
·
Provider substitution does not prove production-provider behavior

مطالعهٔ موارد (case studies)

فایل‌های آزمایشگاه

نیاز: Python 3.10+، فقط کتابخانهٔ استاندارد. فایل‌های fixtures شواهد مصنوعی‌اند. دستورها را در همین پوشه اجرا کنید.

python run_checks.py --inventory
python sqlite_demo.py
python run_checks.py --template fixtures/pending_model.json submission.json --as-of 2026-09-12
python run_checks.py --check fixtures/pending_model.json submission.json

میان دو فرمان آخر، تصمیم و علت‌ها، pointerها، استدلال، تعمیر و محرک بازبینی خود را بنویسید. خروجی STRUCTURE_PASS_SEMANTICS_UNREVIEWED فقط ساختار را تأیید می‌کند. درستی تصمیم و توضیح نیازمند ارزیابی است. template پاسخ نهایی نمی‌دهد و فایل موجود را بازنویسی نمی‌کند.

قواعد در policy.json و نگاشت فیلدها و جدول کامل در resources هستند. ابتدا baseline و drop_add را با درس بخوانید؛ pending_model هدایت‌شده است. سپس tracking_changed، unsupported_token، concurrency_conflict و transfer_provider را مستقل پاسخ دهید. تاریخ نمونه تاریخی است؛ برای ادعای فعلی تاریخ واقعی را ثبت و انقضا را حفظ کنید.

sqlite_demo.py واقعاً SQL را فقط در حافظه اجرا می‌کند؛ اجرای EF، SQL Server یا migration روی پایگاه دادهٔ مشترک نیست. efcore_reference.cs قطعه‌کد آموزشی است و پروژهٔ قابل build نیست. هیچ دادهٔ واقعی یا دسترسی بیرونی لازم نیست. ورودی اصلی را حفظ و تعمیر پیشنهادی را در پاسخ بنویسید.