आप शायद EF उत्प्रवासन गलत कर रहे हैं...
चल रहा है MigrateAsync() शुरू में? आप अपने डाटाबेस मालिक अधिकार दे रहे हैं और कुछ भी गलत नहीं हो रहा है. वहाँ एक बेहतर तरीका है, EFons आप एक नियंत्रित कदम के रूप में चला जाता है, अपने उत्पादन से सुरक्षित रखने के लिए. लेकिन यहाँ कभी-कभी यह बात ठीक है. "गलत तरीका" वास्तव में, जब हर कदम का उपयोग करने के लिए जाँच करें.
अधिकारियों डोम्स: उत्प्रवासन ओवरव्यू | उत्प्रवासन लागू किया जा रहा है | बंडल
"गग" मार्ग (मैं उपयोग)
इस ब्लॉग का उपयोग MigrateAsync() शुरू में - मैं तुम्हें बताने के लिए नहीं कर रहा हूँ। यहाँ है कि मेरे लिए ठीक है, और क्यों यह शायद आप के लिए नहीं है।
मेरे में Program.cs फ़ाइल मेरे पास निम्न हैं:
using (var scope = app.Services.CreateScope())
{
var blogContext = scope.ServiceProvider.GetRequiredService<IMostlylucidDBContext>();
await blogContext.Database.MigrateAsync();
}
MigrateAsync() आवश्यक होने पर स्थगित उत्प्रवासन लागू होता है तथा डाटाबेस को तैयार करता है. सरल - लेकिन समस्या:
- प्रारंभ डिपेंडेंसीज़ - डाटाबेस नीचे? उत्प्रवासन असफल? आपका एएटी प्रारंभ नहीं होगा.
- सुरक्षा उल्लंघन - आपका ऐप की जरूरत है
db_ownerअधिकार। आप सिर्फ तालिका ड्रॉप करने के लिए कुंजी को अपने stugack दे दिया।
क्यों मैं इसे से दूर हो जाता हूँ: सार्वजनिक डाटा, एकल डॉक नेटवर्क, व्यक्तिगत परियोजना. आप शायद नहीं कर सकते.
जब रन समय उत्प्रवासन ठीक हो तो
- स्थानीय डेवी - तेजी से यह समारोह
- निजी परियोजना - कम विस्फोट त्रिज्या, कोई संवेदनशील डाटा नहीं
- डॉक- क़िस्म- डेविल वातावरण - सुविधा की जीत
- योजना बनाना - प्रसंग जो भी हो, लगातार बदल रहा है
जब वे नहीं कर रहे हैं
- मल्टीपल एकाउन्ट - दौड़ की स्थिति ग्रोर
- संवेदनशील डाटा - PIIII, वित्तीय, विधि = उचित अलगाव जरूरी
- वास्तविक उपयोक्ताओं के साथ उत्पाद - उत्प्रवासन = आउटेज
सीधा मार्ग: EF बंडल
एक ईएफबर एक स्व-धनीय एक्जीक्यूटेबल है जिसमें आपका कम्पाइल किया गया है। विचार करो। dotnet ef database update पृथक में पैकेज्ड .exe.
क्यों बंडल जीते:
- नहीं अधिष्ठापित करता है - लक्ष्य SKS या EF क्लिक की आवश्यकता नहीं है
- उचित अलगाव - अनुप्रयोग की आवश्यकता नहीं है
db_owner; सिर्फ CI धावक करता है, सिर्फ तैनातिंग के दौरान - CII दृश्यता - लॉग में असफलता दिखाता है, एएसटी में नहीं दफन
- बैकबैक सुरक्षा - उत्प्रवासन असफल? Dakyमेंट खराब कोड तैनातों के सामने बंद हो जाता है
- आईएस- स्पॉट - ट्रैक्स जो लागू है, केवल क्या जरूरत है
टिप्पणीः उत्पादनकारी सुरक्षा के लिए, उपयोग में पहचान प्रबंधित करें कनेक्शन वाक्यांशों के बजाय. लेकिन इकट्ठा करने के लिए अब भी एक बड़ा कदम है .
Git क्रियाएँ उदाहरण
- 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 }}
एनवायरनमेंट वेरिएबल से मेन्यू तार पढ़ा जा रहा है तथा लंबित उत्प्रवासन पर लागू होता है. यह सिर्फ सफलतापूर्वक लागू होता है.
स्थानीय बंडल
क्या आप चाहते हैं कि आप अपने इलाके में इकट्ठा हों?
केस प्रयोग करें: सीआई से पहले जाँच, डीबी हैंडफ (सईएई, कोई एसईटी आवश्यक नहीं, Conting तैनात किया गया है) Cass, डिबगिंग के साथ --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
वाक्य रचना त्रुटि, प्रतिबन्ध, FK समस्याएँ - सभी - पहले CI या उत्पादन.
परफ़ॉर्मेंस बिल्ड करें
बंडल पीढ़ी धीमा है - बड़ी परियोजनाओं पर 30+ सेकंड. प्रत्येक निर्माण पर तैयार मत करो.
- जब स्थानीय रूप से जांच की जा रही हो तो हस्तचालित बनाएँ
- तैनाती के दौरान सिर्फ सीआई में उत्पन्न करें, हर जय नहीं
- कैश बंडल यदि उत्प्रवासन बदल नहीं गया है
यदि आप सचमुच स्वचालित-पीढ़ी चाहते हैं, एक एमएस बिल्डर लक्ष्य जोड़ें:
<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
बंडल में वैकल्पिक
एसक्यूएल स्क्रिप्ट
एमईटी के बजाय सादा एसक्यूएल बनाएँ. डीबी समीक्षा तथा मौजूदा परिवर्तन प्रबंधन प्रक्रिया के लिए बढ़िया.
# 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
प्रोविडेंस: पूर्ण रूप से दिखाएँ, कोई एसक्यूएल क्लाएंट इसे चला सकता है, संस्करण दोस्ताना ढंग से, डीबी अनुमोदन कार्य फलता है.
कनेक्शनः कोई स्वतः- ट्रैकिंग नहीं (यह प्रयोग करें) --idempotent, हस्तचालित चलाना, यदि स्क्रिप्ट परिवर्धित हैं तो संभावित बहाव.
देखें एसक्यूएल स्क्रिप्ट पर आधिकारिक डॉट्स.
सीआई में एसक्यूएल स्क्रिप्ट
- 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
DACPCPC (सिर्फ एसक्यूएल सर्वर)
डीएसीपीसीसीसी कर रहे हैं स्टेट- आधारित नहीं उत्प्रवासन- आधारित. आप वांछित स्कीमा को परिभाषित करते हैं, और SECAL पैकेज यह लक्ष्य डाटाबेस के खिलाफ है.
SqlPackage.exe /Action:Publish /SourceFile:MyDatabase.dacpac /TargetConnectionString:"..."
प्रोविडेंस: कोड के रूप में स्कीमा, स्वचालित उपयोग करने की पीढ़ी, सब कुछ संभालता है (table, दृश्य, भाषण, अनुक्रमणिका), उत्पादन औज़ार.
कनेक्शनः एसक्यूएल सर्वर केवल दो स्थानों में स्कीमा, (ईएफ मॉडल + एसक्यूएल परियोजना), डिफ़ इंजन अविश्वसनीय विकल्प बनाता है, स्तम्भ का नाम ड्रॉप+add की तरह दिखता है.
देखें एसक्यूल पैकेज्स.
तुलना तालिका
DERATCT ऑटो- ट्रैकर डीईएक्सटीएक्स- ट्रैक्स डीबी- आकार के लिए सबसे अच्छा स्वागत करता है
|----------|----------|---------------|---------------------|--------------|-------------------|
| MigrateAsync() गीत- सूची परियोजना परियोजना नहीं मिली.
सेंटीमीटर ईएफएस सीआर सीआई/ सीडीssssN ( स्वयं के भीतरी- ख) Adviz कुछ UNAYAYYEANT
एसक्यूएल स्क्रिप्टLOMONTHENTHAT- कंट्रोल- नियंत्रण वातावरण DHELLLANK के साथ --idempotent AKYEARYEAR
UGACACMC एसक्यूएल सर्वर ने सत्यापित नहीं किया (एम- आधारित) जीएमएमईएमईएमई जी नहीं
युक्तियाँ
डिज़ाइनर फ़ाइल पकड़ा गया
उत्प्रवासन स्थानीय कार्य करता है लेकिन सीआई में नहीं? जांच आपने दोनों फ़ाइलों को पूरा किया:
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
कनेक्शन स्ट्रिंग प्राथमिकता
--connectionतर्क- वातावरण चर
appsettings.json
सीआई में एनवायरनमेंट वेरिएबल इस्तेमाल करें.
संदर्भ प्रबंधन समय के लिए आईडी चिह्न
एएफ उपकरण आपके डीबी संदर्भ को कम करने की जरूरत है. यदि आपका डीबी संदर्भ एक अलग परियोजना में है या जटिल स्टार्टअप है, औजार 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);
}
}
इस्तेमाल करें: अलग परियोजना में डीबी संदर्भ, जटिल स्टार्टअप में, डिजाइन के समय के लिए उपयोक्ता गोपनीयओं की आवश्यकता होती है.
क्या के बारे में... ?
आम सवाल और धक्का देकर मैं मिल गया है।
"क्यों नहीं केवल रन dotnet ef database update सीआई में?
ऊपर कवर किया गया, लेकिन छोटे संस्करण: इकट्ठा होते हैं पैकमेंट बिल्डर. आपका तैनात चरण EF क्लिक, स्रोत कोड या डिजाइन सेट की आवश्यकता नहीं है. एक सेम परीक्षण, CFConing, और प्रोटेस्टंट - शून्य बहाव में चला जाता है.
"यह एक छोटे से एप्पन के लिए लायक नहीं है?"
शायद आप सोलो, डेटा सार्वजनिक हैं, और विस्फोट त्रिज्या कम है - MigrateAsync() ठीक है. लेकिन पल है कि आप एक दूसरे डेवलपर, संवेदनशील डेटा, या कई वातावरण, अपने लिए भुगतान करता है.
"क्या रोलबैक्स के बारे में?"
EF स्वचालित रोलबैक नहीं करता है. विकल्प:
- बनाएँ (G)
Down()(और) उन लोगों को अपनी तरफ बुलाती होगी - बैकअप से फिर पाएँ
- परिवर्तनों को फिर से लाने के लिए हस्तचालित उत्प्रवासन लिखें
महत्वपूर्ण तंत्रों के लिए: डाटाबेस क्लोन के विरूद्ध सूचनाओं को पहले जाँच करें.
"क्या मैं एक कुएँ के बर्तन में उत्प्रवासन चला सकता हूँ?"
हां. बंडल + इनस्टिटर में ठोस पैटर्न है:
initContainers:
- name: migrate
image: myapp:latest
command: ["./efbundle.exe"]
env:
- name: ConnectionStrings__Default
valueFrom:
secretKeyRef:
name: db-secrets
key: connection-string
पूरी तरह से तैयार करने के लिए संग्राहक इंतजार करता है.
"क्या उद्देश्यवादी / Db अप / अन्य औज़ारों के बारे में? "
वे महान काम करते हैं. फ्लाइडर और Db- अप उनके प्रशंसक हैं. कुंजी भिन्न है: वे उत्प्रवासन विशेष औज़ार हैं, जबकि EFhhs आपके मौजूदा ईएफ मॉडल से आता है.
"मेरा डीजी सभी एसक्यूएल पर पुनर्विचार करना चाहता है इससे पहले कि यह चलता है"
प्रयोक्ता --idempotent स्क्रिप्ट:
dotnet ef migrations script --idempotent --output migrations.sql
DB समीक्षा और अनुमोदन. फिर या तो:
- स्क्रिप्ट को दस्ती रूप से चलाएँ, या स्क्रिप्ट को हस्तचालित चलाएँ
- एक बार स्वीकृत, बंडल चलाना (जो समान बात करता है)
"मैं शून्य नीचे समय के साथ उत्प्रवासन संभाल कैसे करते हैं?"
यही कारण है कि एक तैनाती रणनीति सवाल है, एक उत्प्रवासनी सवाल नहीं है. आम तौर पर:
- उत्प्रवासनों को असंगत रूप से बना दें (जोड़ें स्तम्भों के नलेबल, नाम नहीं)
- नया कोड जो पुराने तथा नए स्कीमा दोनों को हैंडल करता है
- उत्प्रवासन
- केवल नए स्कीमा का प्रयोग करता है
- साफ करें (बाद में पुराने स्तम्भों को निर्मित करें)
बंडल इस को हल नहीं करते - वे बस कदम 3 और अधिक अनुमानीय बनाता है.