Question: I am looking into Migrations in an effort to clean up our deployment processes. The less manual intervention required when pushing a change to production the better.

I have run into 3 major snags with the migrations system. They are show stoppers if I can not figure out a clean way around them.

**1. How do I add Seed data per migration:**

I execute the command "add-migration" which scaffolds a new migration file with Up and Down functions. Now, I want to automatically make changes to the data with both Up and Down changes. I don't want to add the Seed data to the Configuration.Seed method as this runs for all migrations which ends in all sorts of duplication problems.

**2. If the above is not possible, how do I avoid duplications?**

I have an enum that I loop through to add the values to the database.

```
foreach(var enumValue in Enum.GetValues(typeof(Access.Level)))
{
    context.Access.AddOrUpdate(
        new Access { AccessId = ((int)enumValue), Name = enumValue.ToString() }
    );
}
context.SaveChanges();

```

Even though I am using AddOrUpdate, I still get duplicates in the database. The above code brings me to my 3rd and final problem:

**3. How can I seed Primary Keys?**

My enumerable with the above code is:

```
public class Access
{
    public enum Level
    {
        None = 10,
        Read = 20,
        ReadWrite = 30
    }
    public int AccessId { get; set; }
    public string Name { get; set; }
}

```

I am specifying the values that I want as my primary key, but Entity Framework seems to ignore it. They still end up being 1,2,3. How do I get it to be 10,20,30?

Are these limitations of EF at the moment or are they intentional constraints to prevent some other kind of catastrophe I am not seeing?

Answer: 
1. When I have fixed data that I want to insert with a migration, I put the inserts directly in the Up() migration using calls to `Sql("Insert ...")`. See the note halfway down this page: [how to insert fixed data](http://www.asp.net/mvc/tutorials/deployment/visual-studio-web-deployment/preparing-databases)
2. You prevent duplicates in the Seed method by calling the AddOrUpdate overload that takes an identifier expression specifying the natural key - see [this answer](https://stackoverflow.com/a/17719137/150342) and [this blog entry](http://thedatafarm.com/blog/data-access/take-care-with-ef-4-3-addorupdate-method/).
3. Primary keys that are integers are created as identity fields by default. To specify otherwise use the `[DatabaseGenerated(DatabaseGeneratedOption.None)]` attribute

I think this is a good explanation of [Initializer and Seed methods](http://blog.oneunicorn.com/2013/05/28/database-initializer-and-migrations-seed-methods/)

Here is an example of how to use the AddOrUpdate method:

```
foreach(var enumValue in Enum.GetValues(typeof(Access.Level)))
{
    context.Access.AddOrUpdate(
        x => x.Name, //the natural key is "Name"
        new Access { AccessId = ((int)enumValue), Name = enumValue.ToString() }
    );
}

```
OK, so with a bit of bashing I have managed to bash EF into submission.
Here is what I did:

**1.** There is no way that I found to see data for a specific migration. It all must go into the common Configuration.Seed method.

**2.** To avoid duplicates I had to do 2 things.
For my enums, I wrote the following seed code:

```
foreach (var enumValue in Enum.GetValues(typeof(Access.Level)))
{
    var id = (int)enumValue;
    var val = enumValue.ToString();

    if(!context.Access.Any(e => e.AccessId == id))
        context.Access.Add(
            new Access { AccessId = id, Name = val }
        );
}
context.SaveChanges();

```

So basically, just checking if it exists and adding if not

**3.** In order for the above to work, you need to be able to insert Primary Key Values. Luckily for me this table will always have the same static data so I could deactivate the auto increment. To do that, the code looks like:

```
public class Access
{
    public enum Level
    {
        None = 10,
        Read = 20,
        ReadWrite = 30
    }

    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int AccessId { get; set; }
    public string Name { get; set; }
}

```