3

I am experiencing some strange issues with EF7-codefirst migrations and SQL Server on my local machine. When I run the following in command-prompt:

dnx ef migrations add InitialDatabse

It is creating the columns in alphabetical order. From what I remember the default is usually to create the columns in the same order they are in the class.

Here is my concern:
Why is it creating my columns in alphabetical order?

Here are my models and 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; }
}

Here is my InitialDatabase.cs file after adding migrations to the project:

    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);
        });
1

2 Answers 2

2

It is hard to ensure a predictable order, so ordering by property order is currently not implemented. See the discussion here https://github.com/aspnet/EntityFramework/issues/2272

Sign up to request clarification or add additional context in comments.

2 Comments

Is there a setting or anything to specify the order in my DbContext?
You could use Column attributes to specify order. [Column("Name ", Order = 1)]
0

Because .NET Core targets non-Windows platforms, the automated process cannot guarantee that a model's properties are given to the engine in the coded order. Back when I first discovered the issue, I recall it had something to do with Reflection, but not the details.

Anyway, to resolve the issue, use Data Annotations to force your column orders. Note that the actual number you use doesn't need to be in intervals of 1, you can use values like 10, 20, 30 so if you need to move/add a column, you can use a value like 15 without having to readjust every property in your model.

I haven't had success creating a Migration that alters column orders; I just drop/rebuild my tables from scratch.

Modifying Your Example:

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; }
} 

For more information on Data Annotations in code-first, check out the official .NET Core documentation here:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.