【问题标题】:How to rename Primary key Column in code first approach in ASP.net MVC?如何在 ASP.net MVC 的代码优先方法中重命名主键列?
【发布时间】:2017-07-11 15:29:58
【问题描述】:

我使用的是 EF 代码优先方法。我需要重命名我的 PK 列名。

 public class classname
    {
    [Key]
    public int OldId { get; set; }
    }

我需要将 OldId 更改为 NewId。我尝试将我的 OldId 重命名为 NewId,我尝试使用 Migration 更新我的数据库,但这没有帮助。 我尝试在列名和模型中重命名,当我尝试更新我的数据库时再次出现错误。 如何在不丢失数据的情况下重命名主键列?

【问题讨论】:

    标签: asp.net-mvc entity-framework


    【解决方案1】:

    问题是您的代码中不再使用 OldId 但仍在您的数据库中,还是您的问题是 OldId 在您的代码中但在您的数据库中具有不同的列名?

    如果您想告诉实体框架DbSet 中的属性名称在数据库中具有不同的列名称,您可以使用流畅的 API 或数据注释:

    Fluent API 方法

    public class MyDbContext : DbContext
    {
        public DbSet<ClassName> ClassNames {get; set;}
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
             // Tell entity framework that you are now building ClassName:
             var classNameConfig = modelBuilder.Entity<ClassName>();
    
             // ClassName has an int primary key in OldId:
             classNameConfig.HasKey(className => className.OldId);
    
             // "columnX" in the database corresponds with property OldId
             classNameConfig.Property(className => className.OldId)
                 .HasColumnName("columnX");
        }
    }
    

    当然,在这个具体的例子中,这可以连接成一个语句。

    Fluent API 的好处在于,您可以将类与实际的数据库表示断开连接。这向 DbSet 的用户隐藏了实际数据库如何命名其列、列顺序、最小大小、最大大小等。

    只需指定不同的 DbContext,就可以将相同的类与不同的 Db 一起使用。

    例如,如果你想在不同的数据库中使用相同的实体框架类:

    class BaseContext : DbContext
    {
        public DbSet<MyClass> MyClasses {get; set;}
    }
    
    // context to be used with database X:
    class DataBaseXContext : BaseContext
    {
         protected override void OnModelCreating(
    DbModelBuilder modelBuilder)
         {
             // I want to use "columnX" for property A, which is optional:
             modelBuilder.Entity<MyClass>
                 .Property(p => p.A)
                 .HasColumnName("columnX")
                 .IsOptional();
         }
    }
    
    // context to be used with database Y:
    class DataBaseXContext : BaseContext
    {
         protected override void OnModelCreating(DbModelBuilder modelBuilder)
         {
             // I want to use "columnY" for property A, which is required:
             modelBuilder.Entity<MyClass>
                 .Property(p => p.A)
                 .HasColumnName("columnY")
                 .IsRequired();
         }
    }
    

    数据标注法

    如果您绝对确定您希望您的类仅在一个数据库中使用一个预定义模型,您可以使用数据注释。

    但是,您的问题表明,在不同的数据库模型中使用相同的类并不罕见。因此,尽管这种方法非常常用,但我还是敦促您重新考虑使用数据注释的决定。

    public class classname
    {
        [Key]
         [Column("ColumnX")]
         public int OldId { get; set; }
    }
    

    【讨论】:

      【解决方案2】:

      更改 Identity 列可能会导致不稳定,除非您终止所有 Key 约束(所有表关系),否则您无法更改该列的任何内容 太复杂了,我建议你,如果数据不重要,那么只需删除数据库并重新运行 migraions,它将再次重新创建数据库

      【讨论】:

        【解决方案3】:

        实体属性的名称可以与数据库列的名称不同。

        如果您需要更改数据库中列的名称,您可以使用 DBMS 管理器(如果您使用 SQL Server,则使用 SQL Server 企业管理器)或运行正确的 DDL 语句(SQL Server 上的sp_rename)来完成然后使用属性ColumnAttribute在属性上设置新的列名

        [Column("NewId")]
        [Key]
        public int OldId { get; set; }
        

        如果您需要更改代码中的名称而不是数据库上的名称,您可以做类似的事情

        [Column("OldId")]
        [Key]
        public int NewId { get; set; }
        

        在这种情况下,您应该进行重构(如果您有标准的 Visual Studio 键,则使用 F2 重命名;如果您使用的是 resharper,则使用 Ctrl+R、R 重命名)

        如果您需要更改两者,您可以同时进行。

        【讨论】:

          猜你喜欢
          • 2021-07-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-05
          • 2012-02-11
          • 2016-05-21
          相关资源
          最近更新 更多