أنت من المحتمل تَعْملُ EF الهجرة خاطئ... (العربية (Arabic))

أنت من المحتمل تَعْملُ EF الهجرة خاطئ...

Sunday, 23 November 2025

//

9 minute read

جاري التنفيذ MigrateAsync() في البداية؟ أنت تعطي برنامجك قاعدة بياناتك حقوق ملكية وأمل عدم حدوث أي خطأ. هناك طريقة أفضل -- حزم هجرة EF تسمح لك بإدارة الهجرة كخطوة متحكم بها CI ، والحفاظ على تطبيق الإنتاج الخاص بك. ولكن هنا الشيء : أحيانا طريقة "خطأ" هي في الواقع على ما يرام. دعونا نستكشف متى نستخدم كل نهج.

الوثائق الرسمية: لمحة عامة عن الهجرة | تطبيق الهجرات | ملحقات

طريق "الخطأ" (الذي أستخدمه)

استخدامات هذه المدونات MigrateAsync() هذا هو السبب في أن هذا مناسب بالنسبة لي، ولماذا على الأرجح ليس بالنسبة لك.

(ب) في Program.cs ملفّ لديّ ما يلي:

    using (var scope = app.Services.CreateScope())
    {
        var blogContext = scope.ServiceProvider.GetRequiredService<IMostlylucidDBContext>();
        await blogContext.Database.MigrateAsync();
    }

MigrateAsync() في انتظار الهجرة وإنشاء قاعدة البيانات إذا لزم الأمر. بسيطة - ولكن إشكالية:

  1. الاعتماد على بدء البدء -الهجرة تفشل، تطبيقك لن يبدأ
  2. الموضوع: - احتياجاتك db_owner لقد أعطيت للتو الوقت المناسب للمفاتيح لإسقاط الطاولات

لماذا أفلت بفعلتي: بيانات عامة، شبكة (دوكر) وحيدة، مشروع شخصي. من المحتمل أنك لا تستطيع.

عندما يُسرَّ وقت الهجرة

  • المحلية v -سريعاً يَكْثّرُ المراسيم
  • المحل المحل المحل المحل المحل المحل المحل المحل المحل على المحل المحل المحل على المحل المحل المحل - نُظُم تفجيرية منخفضة، لا توجد بيانات حساسة
  • جاريات dv -الفوز بالفوز
  • **** -سيما تتغير باستمرار على أي حال

عندما لا تكون

  • حالات تعدد مرات - ظروف الشغل
  • **** - PII، المالية، المنظمة = الفصل المناسب المطلوب
  • الإنتاج مع المستخدمين الحقيقيين - الهجرة الفاشلة = القصّر

الطريق الصحيح: EF Bundles

A EF حزمة هو a مستقلّ تنفيذي يحتوي الهجرات. فكّر. dotnet ef database update أُدمج في كيان قائم على أساس .exe.

لماذا تربح الحزم:

  • لا تنفيذ تنفيذ تنفيذ - الهدف لا يحتاج إلى SDK أو EF CLI
  • الفصل الصحيح - عدم وجود احتياجات db_ownerلا يفعل ذلك إلا أثناء الوزع فقط.
  • الساعة - الإخفاقات تظهر في سجلات خطوط الأنابيب، لا تُدفن في مرحلة بدء التشغيل
  • سلامة العودة إلى الخلف توقف التنفيذ قبل نشر الشفرة السيئة
  • غير قادر -المسارات التي يتم تطبيقها، وتسير فقط ما هو مطلوب

ملاحظة: لأغراض الأمن، الاستخدام لأغراض الإنتاج، العمر العمران لكن الحزم لا تزال خطوة كبيرة من الهجرة عبر الزمن.

مربع

      - name: Install EF Core tools
        run: dotnet tool install --global dotnet-ef

      - name: Add EF tools to PATH
        run: echo "$HOME/.dotnet/tools" >> $GITHUB_PATH

      - name: Generate EF migration bundle
        run: |
          dotnet ef migrations bundle \
            --project ${{ env.WEB_PROJECT }} \
            --output efbundle.exe \
            --configuration ${{ env.BUILD_CONFIGURATION }} \
            --runtime ${{ env.RUNTIME_IDENTIFIER }} \
            --context AdminDbContext \
        env:
          AdminSite__ConnectionString: ${{ secrets.PROD_SQL_CONNECTIONSTRING }}

      - name: Run EF migration bundle
        run: |
          ./efbundle.exe
        env:
          AdminSite__ConnectionString: ${{ secrets.PROD_SQL_CONNECTIONSTRING }}

الحزمة تقرأ الربط من المتغيرات البيئية وتطبق الهجرات المعلقة. تم تطبيقها بالفعل؟ إنها تخرج بنجاح فقط.

ملحقات محلية

هل تريد أن تختبر قبل أن تدفع؟ تبني الحزم محليا.

حالات الاستخدام: اختبار قبل CC CI، DBA doff (السابق القائم بذاته، لا حاجة إلى SDK)، عمليات نشر، --verbose.

إنشاء مَنْدَل

# Install EF CLI (once)
dotnet tool install --global dotnet-ef

# Basic bundle
dotnet ef migrations bundle \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid \
    --output efbundle.exe

# Self-contained (includes runtime - portable to machines without .NET)
dotnet ef migrations bundle \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid \
    --output efbundle.exe \
    --self-contained

# Cross-platform (e.g., build on Windows, deploy to Linux)
dotnet ef migrations bundle \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid \
    --output efbundle \
    --runtime linux-x64

جاري تشغيل ملحقك

# Using default connection string from appsettings.json
./efbundle.exe

# Override with a specific connection string
./efbundle.exe --connection "Host=localhost;Database=mostlylucid;Username=postgres;Password=secret"

# Using an environment variable (matches your config key)
$env:ConnectionStrings__DefaultConnection="Host=localhost;..." # PowerShell
export ConnectionStrings__DefaultConnection="Host=localhost;..." # Bash
./efbundle.exe

# See what migrations would be applied without running them
./efbundle.exe --dry-run

# Verbose output for debugging
./efbundle.exe --verbose

# Apply migrations up to a specific migration (useful for testing)
./efbundle.exe --target-migration "20231115_AddUserTable"

# Combine options
./efbundle.exe --verbose --dry-run

اختبار محلي

# 1. Create migration
dotnet ef migrations add AddNewFeature \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid

# 2. Build bundle
dotnet ef migrations bundle \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid \
    --output efbundle.exe

# 3. Dry run first
./efbundle.exe --dry-run --verbose

# 4. Run for real
./efbundle.exe --verbose

# 5. Broken? Remove and retry
dotnet ef migrations remove \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid

الأخطاء في الصياغة، انتهاكات القيود، قضايا ف. ك. ثالثاً (ج) أو الإنتاج.

الأداء

يُؤبّطُ الـ -30+ثانية في المشاريع الكبيرة، لا تولد أي بناء

  • يُغيِّر عندما يجري الاختبار محلياً
  • (ب) أن تكون في مركز المعلومات الدولية فقط أثناء النشر، وليس كل العلاقات العامة
  • الحافظات IF الهجرات لم تتغير

إذا كنت تريد حقاً توليد تلقائي، اضف هدف MSBuild:

<Target Name="BuildMigrationBundle">
  <Exec Command="dotnet ef migrations bundle --output $(OutputPath)efbundle.exe --force" />
</Target>

ثم: dotnet build -t:BuildMigrationBundle

النهج المُنْدْلْلْلُ

أفضل من العالمين: الملاءمة محلياً، الأمن في الإنتاج.

if (builder.Environment.IsDevelopment())
{
    using var scope = app.Services.CreateScope();
    var context = scope.ServiceProvider.GetRequiredService<IMostlylucidDBContext>();
    await context.Database.MigrateAsync();
}
// Production: CI pipeline runs the bundle

مُبديلات إلى الملحقات

إعداد بسيط SQL بدلاً من تنفيذي. عظيم بالنسبة لاستعراض DBA والعمليات الحالية لإدارة التغيير.

# All migrations
dotnet ef migrations script --output migrations.sql

# Idempotent (safe to run multiple times) - USE THIS
dotnet ef migrations script --idempotent --output migrations.sql

# Range of migrations
dotnet ef migrations script FromMigration ToMigration --output migrations.sql

Pros: الرؤية الكاملة، أيّ عميل SQL يُمْكِنُ أَنْ يُشغّلَه، نظام تحكم سهل، DBA أعمال الموافقةِ.

كون: لا تتبع تلقائي (الاستخدام) --idempotent)، التنفيذ اليدوي، احتمال الانجراف في حالة تعديل النصوص.

انظر S انظر أُرسِف على رسائل SSQL.

SQlSQLSS مخطوط مخطوط في

- name: Generate and apply migrations
  run: |
    dotnet ef migrations script --idempotent --output migrations.sql
    # SQL Server
    sqlcmd -S ${{ secrets.DB_SERVER }} -d ${{ secrets.DB_NAME }} -i migrations.sql
    # Or PostgreSQL
    PGPASSWORD=${{ secrets.DB_PASSWORD }} psql -h ${{ secrets.DB_HOST }} -f migrations.sql

لجنة مركز PCPAC (الخادم SQL فقط)

ثالثاً - كَانَ - - - - - - - - - - - - - - - - - - غير في البلدان التي تمرأنت تعرّف المخطط المرغوب فيه، و SqlPackage يَمْزّقُه ضدّ قاعدة بيانات الهدفَ.

SqlPackage.exe /Action:Publish /SourceFile:MyDatabase.dacpac /TargetConnectionString:"..."

Pros: ويتعامل مع كل شيء (الجداول، وجهات النظر، البرامج الفرعية، الفهارس)، وأدوات المؤسسة.

كون: خادم SQL فقط، مخطط في مكانين (نموذجات EF + مشروع SQL)، محرّك Diff يجعل خيارات مشكوك فيها، إعادة تسمية الأعمدة تبدو كإسقاط + add.

انظر S انظر مؤدّات Name SSqlPackage.

الجدول

JIU/ chouch / chwest for quest for quals.net au-tracks Auto- traits تطبيق DBA DBA Asss-platform DB |----------|----------|---------------|---------------------|--------------|-------------------| | MigrateAsync() □ مشاريع التنمية/المشاريع الصغيرة □ نعم (السنة) □ نعم □ لا □ نعم □ نعم □ □ نعم □ □ EF Bundles □ CI/CD خطوط الأنابيب □ لا (قائمة بذاتها) □ نعم □ بعض الشيء □ نعم □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □ (ب) البيئات الخاضعة لسيطرة DBB --idempotent □ نعم □ نعم □ نعم □ □ لا □ نعم (على أساس الدولة) □ نعم □ لا □ لا □

نص

المجلدات

الهجرات تعمل محلياً ولكن لا تعمل في دائرة التحقيقات الجنائية؟ كِشِف أنت ملفّف:

  • 20231115_AddUserTable.cs - قانون الهجرة
  • 20231115_AddUserTable.Designer.cs - نموذج العرض

احذف المصمم ملفّ فشل صامت.

dotnet ef migrations bundle --context BlogDbContext --output blog-migrations.exe
dotnet ef migrations bundle --context IdentityDbContext --output identity-migrations.exe

  1. --connection باء - مسائل أخرى
  2. البيئة المتغيرة
  3. appsettings.json

إستعمل بيئة بوصة.

مُرفق

تحتاج أدوات EF إلى إعادة تشغيل مشروعك DbConConse. إذا كان نصك DbConft في مشروع منفصل أو إذا كان لديه مشروع تشغيل معقد ، نفّذ IDesignTimeDbContextFactory<T>:

public class AdminDbContextFactory : IDesignTimeDbContextFactory<AdminDbContext>
{
    public AdminDbContext CreateDbContext(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true)
            .AddEnvironmentVariables()
            .AddUserSecrets<AdminDbContextFactory>()
            .Build();

        var connectionString = config["AdminSite:ConnectionString"]
            ?? throw new InvalidOperationException("Missing connection string");

        var optionsBuilder = new DbContextOptionsBuilder<AdminDbContext>();
        optionsBuilder.UseSqlServer(connectionString, sql => sql.CommandTimeout(120));

        return new AdminDbContext(optionsBuilder.Options);
    }
}

تاريخ الاستخدام: DbContex في مشروع منفصل، بدء معقّد، يحتاج إلى أسرار المستخدم لوقت التصميم.

ماذا عن... ؟

الأسئلة الشائعة و ردة الفعل التي تلقيتها.

"لماذا لا مجرد تشغيل dotnet ef database update " في " تاء "

مغطاة أعلاه، ولكن النسخة القصيرة: الحزم هي قطع أثرية محمولة. خطوة نشرك لا تحتاج إلى EF CLI، شفرة المصدر، أو دقة وقت التصميم. نفس الحزمة تعمل في الاختبار، والتدحرج، والاستعجال - إنجراف الصفر.

"أليس هذا الإفراط في القتل من أجل تطبيق صغير؟"

ربما، إذا كنت منفرداً، البيانات عامة، و نصف قطر الإنفجار منخفض... MigrateAsync() لكن في اللحظة التي تضيف فيها مطوراً ثانياً، بيانات حساسة، أو بيئات متعددة،

"ماذا عن النكسات؟"

EF لا يعمل تلقائي تراجع. خيارات:

  • غير مُنْ مُن م Down() واديرها (لكن عليك أن تكون قد كتبتها)
  • دعم دعم دعم دعم دعم دعم دعم دعم
  • اكتب دليل ترحيل إلى إلغاء التغييرات

بالنسبة للنظم الحرجة: اختبار الانتقالات من قاعدة بيانات إلى استنساخها أولا.

"هل يمكنني إدارة الهجرة في حاوية كوبرنيتس في الحاوية؟"

نعم، بوندل + في الحاوية هو نمط صلب:

initContainers:
  - name: migrate
    image: myapp:latest
    command: ["./efbundle.exe"]
    env:
      - name: ConnectionStrings__Default
        valueFrom:
          secretKeyRef:
            name: db-secrets
            key: connection-string

وتنتظر الحاوية إلى أن تكتمل.

ماذا عن أدوات أخرى؟

وهي تعمل بشكل عظيم. حزم EF هي حل EF المحلي، ولكن & صالح مُرمجججor وقد عقد مؤتمراً بشأن المجموع الفرق الرئيسي: هذه أدوات خاصة بالهجرة، في حين أن حزم الـ EF تأتي من نموذجك الحالي لـ EF.

بلدي DBA يريد أن يستعرض كل SQL قبل تشغيله "

--idempotent

dotnet ef migrations script --idempotent --output migrations.sql

يقوم DBA بمراجعة و الموافقة ثم:

  • جاري التشغيل في النص السابق، أو
  • مرة واحدة معتمدة، تشغيل الحزمة (التي تفعل نفس الشيء)

"كيف يمكنني التعامل مع الهجرة مع الصفر وقت الإنهيار؟"

هذا سؤال إستراتيجي، ليس سؤال هجرة، عموماً:

  1. جعل الهجرات المتوافقة عكسياً (أضافت ad dad dad dad du لا إعادة التسمية)
  2. نشر شفرة جديدة للتعامل مع كل من المخططين القديم والجديد
  3. مرن الهجرة
  4. انشر الرمز الذي يستخدم مفهوم جديد فقط
  5. التنظيف (يسقط الأعمدة القديمة في هجرة لاحقة)

Bundles لا يحلّ هذا - هم فقط يجعلون الخطوة 3 أكثر قابلية للتنبؤ.

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.