সারণী এবং কলামগুলির নাম পরিবর্তন করে সত্ত্বার ফ্রেমওয়ার্ক স্থানান্তর


118

আমি এএ দম্পতি সত্তা এবং তাদের নেভিগেশন বৈশিষ্ট্যগুলির নামকরণ করেছি এবং EF 5 এ একটি নতুন মাইগ্রেশন তৈরি করেছি E ইএফ মাইগ্রেশনে নামকরণের মতো স্বাভাবিকভাবেই এটি ডিফল্টরূপে অবজেক্টগুলি ফেলে দেয় এবং তাদের পুনরায় তৈরি করতে চলেছিল। আমি যা চাইছিলাম তা নয় তাই আমাকে স্ক্র্যাচ থেকে মাইগ্রেশন ফাইলটি তৈরি করতে হবে।

    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

আমি টেবিলগুলি সংযুক্ত করে বিদেশী কী এবং সূচিগুলি বাদ দিচ্ছি, তারপরে আমি টেবিলগুলি এবং বিদেশী কী কলামটির নাম পরিবর্তন করছি, তারপরে আমি আবার সূচি এবং বিদেশী কীগুলি যুক্ত করছি। আমি ধরে নিয়েছি এটি কাজ করবে তবে আমি একটি এসকিউএল ত্রুটি পাচ্ছি।

এমএসজি 15248, স্তর 11, রাজ্য 1, প্রক্রিয়া sp_rename, লাইন 215 হয় প্যারামিটার @objname অস্পষ্ট বা দাবিযুক্ত @objtype (COLUMN) ভুল। Msg 4902, স্তর 16, রাজ্য 1, লাইন 10 অবজেক্টটি "dbo.ReportSections" খুঁজে পাচ্ছে না কারণ এটি বিদ্যমান নেই বা আপনার অনুমতি নেই।

আমি এখানে কী ভুল তা জানার জন্য খুব সহজ সময় পাচ্ছি না। যে কোনও অন্তর্দৃষ্টি মারাত্মক সহায়ক হবে।


উপরের কোন লাইন ব্যর্থ? আপনি কি এসকিউএল সার্ভার প্রোফাইলার এ মাইগ্রেশনটি সনাক্ত করতে এবং সংশ্লিষ্ট এসকিউএল চেক করতে পারেন?
Albin Sunnanbo

উত্তর:


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অভ্যন্তরীণভাবে ব্যবহার করে যা কিছু সীমাবদ্ধতা ব্যবহার করে uses সুতরাং আপনার যদি কোনও টেবিলের নাম থাকে যা এতে বিন্দুযুক্ত থাকে যেমন "সাবসিস্টেমএ টেবিলনাম" তবে ব্যবহার করুন:RenameColumn("dbo.[SubSystemA.Tablename]", "OldColumnName", "NewColumnName");
ইলান

10
এটি বিদেশী কীগুলিতে উল্লিখিত কলামগুলি আপডেট করে বলে মনে হচ্ছে, তবে এটি এফকে নিজেই নতুন নাম দেয় না। যা লজ্জাজনক, তবে সম্ভবত পৃথিবীর শেষ না হওয়া অবধি যদি আপনার একেবারে নামটির পরে কোনও এফকে উল্লেখ করার প্রয়োজন না হয়।
মাইকসিজ

9
@ মাইকসিজ আপনি RenameIndex(..)নিজের নামান্তর করতে নিজের মাইগ্রেশনে ব্যবহার করতে পারেন
জোব্রোকহাস

1
কলামটির নাম পরিবর্তন করার সময় আমি ব্যতিক্রম পাচ্ছি। পুনরায় নাম টেবিল প্রয়োগ করা হয়নি বলেই সম্ভবত। আমাকে এটিকে দুটি মাইগ্রেশনে বিভক্ত করতে হয়েছিল
জোসে মার্টিনেজ

EF6 এর সাথে, RenameTable(..)এফকে এবং পিকে এর নতুন নামকরণ করুন। সঠিক শোনাচ্ছে না তবে এটি আমার পক্ষে কাজ করেছে। এটি সঠিক পদ্ধতিতে টি-এসকিউএল তৈরি করে execute sp_rename ...। আপনি যদি আপডেট-ডাটাবেস-ভারবোজ করেন তবে আপনি এটি নিজের জন্য দেখতে পাবেন।
জিওভান্নি

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
মনোযোগ দিন এই পোস্টটি ইএফ কোরের জন্য নয়
হোসেইন নারিমণি র‌্যাড

6
আমি মনে করি আপনার কেবলমাত্র একটি স্থানান্তর প্রয়োজন, তবে এখনও দুটি পদক্ষেপ। 1. বৈশিষ্ট্য যুক্ত করুন এবং "পুনরায় নামকরণ মাইগ্রেশন" তৈরি করুন 2. কেবলমাত্র সম্পত্তির নাম পরিবর্তন করুন। এটাই. যেভাবেই হোক না কেন, এটি আমার বেশ কয়েকবার সময় সাশ্রয় করেছে। ধন্যবাদ!
ক্রিস্পি নিনজা

1
আমি এখানে উল্লিখিত পদক্ষেপগুলি অনুসরণ করেছিলাম এবং এটি সফল হয়েছিল। আমি কোনও বিদ্যমান ডেটা হারিয়ে ফেলিনি। যা আমি সত্যিই চেয়েছিলাম, ডেটা না হারাতে পরিবর্তন করুন। তবে আমি ক্লাসের সম্পত্তির নাম পরিবর্তন করে নিরাপদ পক্ষের জন্য আলাদা মাইগ্রেশন চালাচ্ছি।
মনোজব 86

19

হোসেইন নারিমানি র‌্যাডের উত্তরের উপর কিছুটা প্রসারিত করতে, আপনি যথাক্রমে System.Comp घटकModel.DataAnnotations.Schema.TableAttribute এবং System.Comp घटकModel.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

EF কোরে, আমি সারণী এবং কলামগুলির নাম পরিবর্তন করতে নিম্নলিখিত বিবৃতিগুলি ব্যবহার করি:

টেবিলগুলির নামকরণের জন্য:

    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 তে কোডটি চেষ্টা করেছি (কোডের প্রথম সত্তার নাম)। আমি কেবল ক্লাসটির নাম পরিবর্তন করে প্যাকেজ ম্যানেজার কনসোল এবং ভয়েলা ব্যবহার করে একটি মাইগ্রেশন যুক্ত করেছি, রেনামেটেবল (...) ব্যবহার করে একটি মাইগ্রেশন আমার জন্য স্বয়ংক্রিয়ভাবে তৈরি হয়েছিল। আমাকে স্বীকার করতে হবে যে সত্তার একমাত্র পরিবর্তনই এটির নাম পরিবর্তন করছিল তাই কোনও নতুন কলাম বা নতুন নামকরণকৃত কলাম নেই তাই আমি নিশ্চিত হতে পারি না যে এটি কোনও EF6 জিনিস বা ঠিক যে EF (সর্বদা) এধরনের সরল স্থানান্তর সনাক্ত করতে সক্ষম ছিল।


2
আমি এই 6.1.3 সঙ্গে এটি সঠিকভাবে টেবিল নামান্তর নেই নিশ্চিত করতে পারেন (নামান্তর করতে ভুলবেন না DbSetআপনার DatabaseContextপাশাপাশি)। প্রাথমিক কী পরিবর্তন করা সমস্যার কারণ হয়। স্থানান্তর এটি মুছতে এবং একটি নতুন তৈরি করার চেষ্টা করবে। সুতরাং আপনাকে এটি সামঞ্জস্য করতে হবে এবং শেভের উত্তর হিসাবে করা উচিত, কলামটির নাম পরিবর্তন করুন।
কুলারবাইটস

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");
            });
     }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.