एंटिटी फ्रेमवर्क माइग्रेशन का नामकरण सारणी और स्तंभ


118

मैंने कुछ युगल संस्थाओं और उनके नेविगेशन गुणों का नाम बदला और EF 5 में एक नया माइग्रेशन उत्पन्न किया। जैसा कि ईएफ माइग्रेशन में नाम बदलने के साथ होता है, डिफ़ॉल्ट रूप से यह वस्तुओं को छोड़ने और उन्हें फिर से बनाने के लिए जा रहा था। यही कारण है कि मैं ऐसा नहीं चाहता था इसलिए मुझे स्क्रैच से माइग्रेशन फ़ाइल का निर्माण करना पड़ा।

    public override void Up()
    {
        DropForeignKey("dbo.ReportSectionGroups", "Report_Id", "dbo.Reports");
        DropForeignKey("dbo.ReportSections", "Group_Id", "dbo.ReportSectionGroups");
        DropForeignKey("dbo.Editables", "Section_Id", "dbo.ReportSections");
        DropIndex("dbo.ReportSectionGroups", new[] { "Report_Id" });
        DropIndex("dbo.ReportSections", new[] { "Group_Id" });
        DropIndex("dbo.Editables", new[] { "Section_Id" });

        RenameTable("dbo.ReportSections", "dbo.ReportPages");
        RenameTable("dbo.ReportSectionGroups", "dbo.ReportSections");
        RenameColumn("dbo.ReportPages", "Group_Id", "Section_Id");

        AddForeignKey("dbo.ReportSections", "Report_Id", "dbo.Reports", "Id");
        AddForeignKey("dbo.ReportPages", "Section_Id", "dbo.ReportSections", "Id");
        AddForeignKey("dbo.Editables", "Page_Id", "dbo.ReportPages", "Id");
        CreateIndex("dbo.ReportSections", "Report_Id");
        CreateIndex("dbo.ReportPages", "Section_Id");
        CreateIndex("dbo.Editables", "Page_Id");
    }

    public override void Down()
    {
        DropIndex("dbo.Editables", "Page_Id");
        DropIndex("dbo.ReportPages", "Section_Id");
        DropIndex("dbo.ReportSections", "Report_Id");
        DropForeignKey("dbo.Editables", "Page_Id", "dbo.ReportPages");
        DropForeignKey("dbo.ReportPages", "Section_Id", "dbo.ReportSections");
        DropForeignKey("dbo.ReportSections", "Report_Id", "dbo.Reports");

        RenameColumn("dbo.ReportPages", "Section_Id", "Group_Id");
        RenameTable("dbo.ReportSections", "dbo.ReportSectionGroups");
        RenameTable("dbo.ReportPages", "dbo.ReportSections");

        CreateIndex("dbo.Editables", "Section_Id");
        CreateIndex("dbo.ReportSections", "Group_Id");
        CreateIndex("dbo.ReportSectionGroups", "Report_Id");
        AddForeignKey("dbo.Editables", "Section_Id", "dbo.ReportSections", "Id");
        AddForeignKey("dbo.ReportSections", "Group_Id", "dbo.ReportSectionGroups", "Id");
        AddForeignKey("dbo.ReportSectionGroups", "Report_Id", "dbo.Reports", "Id");
    }

सभी मुझे क्या करना कोशिश कर रहा हूँ नाम बदलने है dbo.ReportSectionsकरने के लिए dbo.ReportPagesऔर उसके बाद dbo.ReportSectionGroupsकरने के लिए dbo.ReportSections। तब मैं पर विदेशी कुंजी स्तंभ नाम बदलने की आवश्यकता dbo.ReportPagesसे Group_Idकरने के लिए Section_Id

मैं तालिकाओं को जोड़ने वाली विदेशी कुंजियों और सूचियों को एक साथ छोड़ रहा हूं, फिर मैं तालिकाओं और विदेशी कुंजी स्तंभ का नाम बदल रहा हूं, फिर मैं अनुक्रमित और विदेशी कुंजियों को फिर से जोड़ रहा हूं। मुझे लगता है कि यह काम करने वाला था, लेकिन मुझे एक SQL त्रुटि मिल रही है।

Msg 15248, स्तर 11, राज्य 1, प्रक्रिया sp_rename, लाइन 215 या तो पैरामीटर @objname अस्पष्ट है या दावा किया गया @objtype (COLUMN) गलत है। Msg 4902, स्तर 16, राज्य 1, पंक्ति 10 ऑब्जेक्ट "dbo.ReportSections" नहीं ढूँढ सकता क्योंकि यह मौजूद नहीं है या आपके पास अनुमतियाँ नहीं हैं।

मुझे पता नहीं चल रहा है कि यहां क्या गलत है। किसी भी अंतर्दृष्टि काफी मददगार होगा।


उपरोक्त में से कौन सी रेखा विफल है? क्या आप SQL Server Profiler में माइग्रेशन का पता लगा सकते हैं और संबंधित SQL को चेक कर सकते हैं?
अल्बिन सुन्नान्बो

जवाबों:


143

कोई बात नहीं। मैं इस तरह से और अधिक जटिल बना रहा था कि यह वास्तव में होना चाहिए।

यह वह सब था जिसकी मुझे जरूरत थी। नाम बदलने के तरीके बस sp_rename सिस्टम संग्रहीत कार्यविधि के लिए एक कॉल उत्पन्न करते हैं और मुझे लगता है कि नए कॉलम नाम के साथ विदेशी कुंजी सहित, सब कुछ का ख्याल रखा।

public override void Up()
{
    RenameTable("ReportSections", "ReportPages");
    RenameTable("ReportSectionGroups", "ReportSections");
    RenameColumn("ReportPages", "Group_Id", "Section_Id");
}

public override void Down()
{
    RenameColumn("ReportPages", "Section_Id", "Group_Id");
    RenameTable("ReportSections", "ReportSectionGroups");
    RenameTable("ReportPages", "ReportSections");
}

29
उन तालिका नामों से सावधान रहें जिनके पास डॉट्स हैं। RenameColumnएक sp_renameटी-एसक्यूएल स्टेटमेंट जेनरेट करता है parsenameजो आंतरिक रूप से उपयोग करता है जिसकी कुछ सीमाएं हैं। इसलिए यदि आपके पास एक तालिका का नाम है, जिसमें डॉट्स हैं जैसे "सबसिस्टम.एटबलन" तो उपयोग करें:RenameColumn("dbo.[SubSystemA.Tablename]", "OldColumnName", "NewColumnName");
इलान

10
यह फॉरेन कीज़ में संदर्भित कॉलम को अपडेट करने के लिए लगता है, लेकिन यह FK का नाम नहीं लेता है। जो एक शर्म की बात है, लेकिन शायद दुनिया का अंत नहीं है जब तक कि आपको इसके नाम से बाद में एफके को संदर्भित करने की आवश्यकता न हो।
mikesigs

9
@mikesigs आप RenameIndex(..)अपने प्रवास में इसका नाम बदलने के लिए उपयोग कर सकते हैं
जोबोराहॉस

1
कॉलम का नाम बदलने पर मुझे एक अपवाद मिल रहा है। शायद इसलिए कि नाम बदलने की मेज अभी भी लागू नहीं है। मुझे इसे दो
प्रवासों

EF6 के साथ, RenameTable(..)FK's और PK का नाम बदलने के लिए उपयोग करें। सही नहीं लगता, लेकिन यह मेरे लिए काम कर रहा है। यह वह विधि है जो सही T-SQL ( execute sp_rename ...) बनाती है। यदि आप अपडेट-डेटाबेस -verbose करते हैं, तो आप इसे अपने लिए देखेंगे।
गियोवन्नी

44

यदि आपको मैन्युअल रूप से माइग्रेशन क्लास में आवश्यक कोड लिखना / बदलना पसंद नहीं है, तो आप एक दो-चरण दृष्टिकोण का पालन कर सकते हैं जो स्वचालित रूप RenameColumnसे आवश्यक कोड बनाते हैं :

चरण एक का उपयोग ColumnAttributeनए स्तंभ नाम और फिर ऐड-माइग्रेशन (उदाहरण के लिए Add-Migration ColumnChanged) का उपयोग करने के लिए करें

public class ReportPages
{
    [Column("Section_Id")]                 //Section_Id
    public int Group_Id{get;set}
}

चरण-दो संपत्ति का नाम बदलते हैं और फिर Add-Migration ColumnChanged -forceसे पैकेज मैनेजर कंसोल में एक ही माइग्रेशन (जैसे ) पर लागू होते हैं

public class ReportPages
{
    [Column("Section_Id")]                 //Section_Id
    public int Section_Id{get;set}
}

यदि आप प्रवासन वर्ग को देखते हैं तो आप स्वचालित रूप से उत्पन्न कोड देख सकते हैं RenameColumn


आप एक ही माइग्रेशन को दो बार कैसे जोड़ सकते हैं? जब मैं यह कोशिश करता हूं, मुझे मिलता है:The name 'Rename_SalesArea' is used by an existing migration.
एंड्रयू एस

-forceऐड-माइग्रेशन का उपयोग करते समय पैरामीटर पर एक नज़र डालें
होसैन नारिमनी रेड

2
यह भी ध्यान दें कि यह पोस्ट EF कोर के लिए नहीं है
होसैन नरीमनी रेड

6
मुझे लगता है कि आपको केवल एक प्रवास की आवश्यकता है, लेकिन फिर भी दो चरण। 1. विशेषता जोड़ें और "नाम बदलें" बनाएं 2. संपत्ति का नाम बदलें। बस। किसी भी तरह से, यह सिर्फ मुझे एक टन बचा लिया। धन्यवाद!
क्रिस्पी निंजा

1
मैंने यहां बताए गए चरणों का पालन किया और यह सफल रहा। मैंने कोई मौजूदा डेटा नहीं खोया। कि मैं वास्तव में क्या चाहता था, डेटा खोए बिना बदलाव करें। लेकिन मैं सुरक्षित पक्ष के लिए, वर्ग के संपत्ति नाम का नाम बदलने के बाद अलग-अलग माइग्रेशन चलाता हूं।
मनोजबिरी Man

19

होसैन नरीमनी रेड के उत्तर पर थोड़ा विस्तार करने के लिए, आप क्रमशः System.ComponentModel.DataAnnotations.Schema.TableAttribute और System.ComponentModel.DataAnnotations.Schema.ColumnAttribute पर एक टेबल और कॉलम दोनों का नाम बदल सकते हैं।

इसके कुछ फायदे हैं:

  1. इससे न केवल नाम माइग्रेशन अपने आप बन जाएगा, बल्कि
  2. यह किसी भी विदेशी कुंजी को स्वादिष्ट रूप से हटा देगा और नए टेबल और कॉलम नामों के विरुद्ध उन्हें फिर से बनाएगा, विदेशी कुंजी और उचित नाम देगा।
  3. यह सब बिना किसी टेबल डेटा को खोए

उदाहरण के लिए, जोड़ना [Table("Staffs")]:

[Table("Staffs")]
public class AccountUser
{
    public long Id { get; set; }

    public long AccountId { get; set; }

    public string ApplicationUserId { get; set; }

    public virtual Account Account { get; set; }

    public virtual ApplicationUser User { get; set; }
}

माइग्रेशन उत्पन्न करेगा:

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropForeignKey(
            name: "FK_AccountUsers_Accounts_AccountId",
            table: "AccountUsers");

        migrationBuilder.DropForeignKey(
            name: "FK_AccountUsers_AspNetUsers_ApplicationUserId",
            table: "AccountUsers");

        migrationBuilder.DropPrimaryKey(
            name: "PK_AccountUsers",
            table: "AccountUsers");

        migrationBuilder.RenameTable(
            name: "AccountUsers",
            newName: "Staffs");

        migrationBuilder.RenameIndex(
            name: "IX_AccountUsers_ApplicationUserId",
            table: "Staffs",
            newName: "IX_Staffs_ApplicationUserId");

        migrationBuilder.RenameIndex(
            name: "IX_AccountUsers_AccountId",
            table: "Staffs",
            newName: "IX_Staffs_AccountId");

        migrationBuilder.AddPrimaryKey(
            name: "PK_Staffs",
            table: "Staffs",
            column: "Id");

        migrationBuilder.AddForeignKey(
            name: "FK_Staffs_Accounts_AccountId",
            table: "Staffs",
            column: "AccountId",
            principalTable: "Accounts",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);

        migrationBuilder.AddForeignKey(
            name: "FK_Staffs_AspNetUsers_ApplicationUserId",
            table: "Staffs",
            column: "ApplicationUserId",
            principalTable: "AspNetUsers",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropForeignKey(
            name: "FK_Staffs_Accounts_AccountId",
            table: "Staffs");

        migrationBuilder.DropForeignKey(
            name: "FK_Staffs_AspNetUsers_ApplicationUserId",
            table: "Staffs");

        migrationBuilder.DropPrimaryKey(
            name: "PK_Staffs",
            table: "Staffs");

        migrationBuilder.RenameTable(
            name: "Staffs",
            newName: "AccountUsers");

        migrationBuilder.RenameIndex(
            name: "IX_Staffs_ApplicationUserId",
            table: "AccountUsers",
            newName: "IX_AccountUsers_ApplicationUserId");

        migrationBuilder.RenameIndex(
            name: "IX_Staffs_AccountId",
            table: "AccountUsers",
            newName: "IX_AccountUsers_AccountId");

        migrationBuilder.AddPrimaryKey(
            name: "PK_AccountUsers",
            table: "AccountUsers",
            column: "Id");

        migrationBuilder.AddForeignKey(
            name: "FK_AccountUsers_Accounts_AccountId",
            table: "AccountUsers",
            column: "AccountId",
            principalTable: "Accounts",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);

        migrationBuilder.AddForeignKey(
            name: "FK_AccountUsers_AspNetUsers_ApplicationUserId",
            table: "AccountUsers",
            column: "ApplicationUserId",
            principalTable: "AspNetUsers",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);
    }

1
ऐसा लगता है कि यह तालिका विशेषता को जोड़ने के लिए डिफ़ॉल्ट होना चाहिए, चीजों को इतना सरल बनाता है।
पैट्रिक

17

ईएफ कोर में, मैं तालिकाओं और स्तंभों का नाम बदलने के लिए निम्नलिखित कथनों का उपयोग करता हूं:

तालिका का नाम बदलने के लिए:

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.RenameTable(name: "OldTableName", schema: "dbo", newName: "NewTableName", newSchema: "dbo");
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.RenameTable(name: "NewTableName", schema: "dbo", newName: "OldTableName", newSchema: "dbo");
    }

स्तंभों का नाम बदलने के लिए:

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.RenameColumn(name: "OldColumnName", table: "TableName", newName: "NewColumnName", schema: "dbo");
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.RenameColumn(name: "NewColumnName", table: "TableName", newName: "OldColumnName", schema: "dbo");
    }

3

एफई कोर में, आप उस माइग्रेशन को बदल सकते हैं जो ऐड माइग्रेशन के बाद बनाया गया था। और फिर अपडेट-डेटाबेस करें। एक नमूना नीचे दिया गया है:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.RenameColumn(name: "Type", table: "Users", newName: "Discriminator", schema: "dbo");
}

protected override void Down(MigrationBuilder migrationBuilder)
{            
    migrationBuilder.RenameColumn(name: "Discriminator", table: "Users", newName: "Type", schema: "dbo");
}

2

मैंने EF6 (कोड फर्स्ट यूनिट नाम बदलें) में भी यही कोशिश की थी। मैंने बस क्लास का नाम बदला और पैकेज मैनेजर कंसोल और वॉयला का उपयोग करके एक माइग्रेशन जोड़ा, मेरे लिए RenameTable (...) का उपयोग करके एक माइग्रेशन स्वचालित रूप से जेनरेट किया गया था। मुझे यह स्वीकार करना होगा कि मैंने यह सुनिश्चित कर लिया था कि इकाई में केवल परिवर्तन ही इसका नाम बदल रहा था इसलिए कोई नया कॉलम या नामांकित कॉलम नहीं था, इसलिए मैं निश्चित नहीं हो सकता कि यह EF6 चीज है या सिर्फ EF था (हमेशा) ऐसे सरल माइग्रेशन का पता लगाने में सक्षम था।


2
मैं 6.1.3 के साथ इसकी पुष्टि कर सकता हूं। यह सही ढंग से तालिका का नाम बदल देता है ( DbSetअपने DatabaseContextरूप में अच्छी तरह से नाम बदलना मत भूलना )। प्राथमिक कुंजी को बदलने से परेशानी होती है। माइग्रेशन इसे हटाने और एक नया बनाने का प्रयास करेगा। तो आपको इसे समायोजित करने की आवश्यकता है और जैसा कि चेव का जवाब है, कॉलम का नाम बदलें।
CularBytes

1

तालिका नाम और स्तंभ नाम मानचित्रण के भाग के रूप में निर्दिष्ट किए जा सकते हैं DbContext। फिर इसे पलायन में करने की कोई आवश्यकता नहीं है।

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Restaurant>()
            .HasMany(p => p.Cuisines)
            .WithMany(r => r.Restaurants)
            .Map(mc =>
            {
                mc.MapLeftKey("RestaurantId");
                mc.MapRightKey("CuisineId");
                mc.ToTable("RestaurantCuisines");
            });
     }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.