ASP.NET 5 EF7 代码优先迁移默认按字母顺序创建列

Posted

技术标签:

【中文标题】ASP.NET 5 EF7 代码优先迁移默认按字母顺序创建列【英文标题】:ASP.NET 5 EF7 code-first migrations is creating columns in alphabetical order by default 【发布时间】:2016-04-14 22:00:55 【问题描述】:

我在本地计算机上遇到了 EF7-codefirst 迁移和 SQL Server 的一些奇怪问题。当我在命令提示符中运行以下命令时:

dnx ef migrations add InitialDatabse

它正在按字母顺序创建列。据我记得,默认设置通常是按照它们在类中的相同顺序创建列。

这是我的担忧: 为什么它按字母顺序创建我的列?

这是我的模型和 Dbcontext:

public class Customer

    public int Id  get; set; 
    public string Name  get; set; 
    public DateTime CreatedDate  get; set;  = DateTime.Now;
    public string CreatedBy  get; set; 
    public DateTime? ModifiedDate  get; set; 
    public string ModifiedBy  get; set; 

    // Navigation properties
    public ICollection<Contact> Contacts  get; set; 


public class Contact

    public int Id  get; set; 
    public string FirstName  get; set; 
    public string LastName  get; set; 
    public string Title  get; set; 
    public string Email  get; set; 
    public DateTime CreatedDate  get; set;  = DateTime.Now;
    public string CreatedBy  get; set; 
    public DateTime? ModifiedDate  get; set; 
    public string ModifiedBy  get; set; 


public class ApplicationDbContext : DbContext

    public ApplicationDbContext ()
    
        Database.EnsureCreated();
    

    public DbSet<Customer> Customers  get; set; 
    public DbSet<Contact> Contacts  get; set; 

这是我将迁移添加到项目后的 InitialDatabase.cs 文件:

    migrationBuilder.CreateTable(
        name: "Customer",
        columns: table => new
        
            Id = table.Column<int>(nullable: false)
                .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
            CreatedBy = table.Column<string>(nullable: true),
            CreatedDate = table.Column<DateTime>(nullable: false),
            ModifiedBy = table.Column<string>(nullable: true),
            ModifiedDate = table.Column<DateTime>(nullable: true),
            Name = table.Column<string>(nullable: true)
        ,
        constraints: table =>
        
            table.PrimaryKey("PK_Customer", x => x.Id);
        );
    migrationBuilder.CreateTable(
        name: "Contact",
        columns: table => new
        
            Id = table.Column<int>(nullable: false)
                .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
            CreatedBy = table.Column<string>(nullable: true),
            CreatedDate = table.Column<DateTime>(nullable: false),
            CustomerId = table.Column<int>(nullable: true),
            Email = table.Column<string>(nullable: true),
            FirstName = table.Column<string>(nullable: true),
            LastName = table.Column<string>(nullable: true),
            ModifiedBy = table.Column<string>(nullable: true),
            ModifiedDate = table.Column<DateTime>(nullable: true),
            Title = table.Column<string>(nullable: true)
        ,
        constraints: table =>
        
            table.PrimaryKey("PK_Contact", x => x.Id);
            table.ForeignKey(
                name: "FK_Contact_Customer_CustomerId",
                column: x => x.CustomerId,
                principalTable: "Customer",
                principalColumn: "Id",
                onDelete: ReferentialAction.Restrict);
        );

【问题讨论】:

同样的问题:***.com/questions/33752065/… 【参考方案1】:

由于 .NET Core 面向非 Windows 平台,因此自动化过程无法保证模型的属性按编码顺序提供给引擎。当我第一次发现这个问题时,我记得它与反射有关,但与细节无关。

无论如何,要解决此问题,请使用数据注释来强制您的列顺序。请注意,您使用的实际数字不需要以 1 为间隔,您可以使用 10、20、30 之类的值,因此如果您需要移动/添加列,您可以使用 15 之类的值而无需重新调整模型中的每个属性。

我没有成功创建改变列顺序的迁移;我只是从头开始删除/重建我的表。

修改你的例子:

public class Customer

    [Column(Order = 10)]
    public int Id  get; set; 

    [Column(Order = 20)]
    public string Name  get; set; 

    [Column(Order = 30)]
    public DateTime CreatedDate  get; set;  = DateTime.Now;

    [Column(Order = 40)]
    public string CreatedBy  get; set; 

    [Column(Order = 50)]
    public DateTime? ModifiedDate  get; set; 

    [Column(Order = 60)]
    public string ModifiedBy  get; set; 

    // Navigation properties
    public ICollection<Contact> Contacts  get; set; 
 

有关代码优先中的数据注释的更多信息,请在此处查看官方 .NET Core 文档:

https://msdn.microsoft.com/en-us/library/jj591583(v=vs.113).aspx

【讨论】:

【参考方案2】:

很难保证一个可预测的顺序,所以目前还没有实现按属性排序。 请参阅此处的讨论https://github.com/aspnet/EntityFramework/issues/2272

【讨论】:

我的 DbContext 中是否有设置或任何东西来指定顺序? 您可以使用列属性来指定顺序。 [Column("Name", Order = 1)]

以上是关于ASP.NET 5 EF7 代码优先迁移默认按字母顺序创建列的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Identity ASP.NET Core 通过代码优先迁移为用户和角色播种

如何使用 EF Core 代码优先迁移为 ASP.NET Core MVC 配置 N 层架构

无法在 .NET 中的实体框架代码优先方法中迁移 AspNetUser 实体

ASP.NET Mvc5+EF7

ASP.NET vNext EF7 dbContext 问题

在带有 EF7 的 ASP.NET5.0 中添加连接字符串以使用 dll 存储库库(基于 EF6)