Question

I am working on a school project using ASP.NET MCV4, EF6, Code-First models. Now, I am wondering how should I fill the database with sample data. I checked migrations, but I don't want to mess with the db structure. I just want to insert data, I tried this:

namespace Autokereskedes.Models
{
    public class _SampleData : DropCreateDatabaseIfModelChanges<AutoDb>
    {
        protected override void Seed(AutoDb context)
        {
            new Autokereskedes.Models.SampleData.Users().List().ForEach(u=>context.Users.Add(u));

            new Autokereskedes.Models.SampleData.Cars().List().ForEach(c => context.Cars.Add(c));

        }
    }
}

namespace Autokereskedes.Models.SampleData
{
    public class Users
    {
        public List<User> List()
        {
            var crypto = new SimpleCrypto.PBKDF2();
            var salt = Autokereskedes.Controllers.AccountController.PasswordSalt;
            return new List<User> 
            {
                new User { 
                    UserId = Guid.NewGuid(), 
                    Email = "admin@autoker.hu", 
                    Password = crypto.Compute("admin",salt),
                    Phone = "+36 20 XXX YYZZ",
                    Banned = false,
                    Country = "Hungary",
                    City = "Szeged",
                    Street = "DivisonByZero street 1/0",
                    ZipCode = 1100,
                    RegistrationDate = DateTime.Now
                },
                new User { 
                    UserId = Guid.NewGuid(), 
                    Email = "user@autoker.hu", 
                    Password = crypto.Compute("user",salt),
                    Phone = "+36 20 XXX YYZZ",
                    Banned = false,
                    Country = "Hungary",
                    City = "Szeged",
                    Street = "DivisonByZero street 2/0",
                    ZipCode = 1100,
                    RegistrationDate = DateTime.Now
                }
            };
        }
    }
}

It is working, I thought. But how should I insert data that has foreign keys? I saw a tutorial where they used a single file for all the List<>-s and in the foreign key field used something like this: Genre = genres.Single(g => g.Name == "Jazz"). I can't really copy that now.

namespace Autokereskedes.Models.SampleData
{
    public class Cars
    {
        public List<Car> List()
        {
            return new List<Car>
            {
                new Car {
                    CarId = Guid.NewGuid(),
                    DepoId = now what
                },
                new Car {

                }
            };
        }
    }
}
Was it helpful?

Solution

When you seed the data, you need to account for the foreign key relationships... eventually.

return new List<Car>
{
    new Car {
        CarId = Guid.NewGuid(),
        DepoId = now what // it depends, is this a required relationship?
    },
    new Car {
    }
};

If DepoId is an optional relationship, you can just wait until you have a Depo & DepoId before setting up this property. Otherwise if it is required, you need to set it up before you insert it into the context.

protected override void Seed(AutoDb context)
{
    new Autokereskedes.Models.SampleData.Users().List()
        .ForEach(u=>context.Users.Add(u));
    var cars = new Autokereskedes.Models.SampleData.Cars().List();
    var depos = new Autokereskedes.Models.SampleData.Depos().List();
    foreach (var car in cars)
    {
        car.DepoId = depos.FirstOrDefault(x => x.DepoId == ...?);

        context.Cars.Add(car);
    }
}

I suppose the question is, how do you decide which depo should be assigned to each car?

Another way to do it, since your Depo entities are a dependency and you need to resolve them first, would be to pass your depos to your cars list method:

var depos = new Autokereskedes.Models.SampleData.Depos().List();
depos.ForEach(d => context.Depos.Add(d));
//context.SaveChanges(); no need for this since your id's are Guid's
var cars = new Autokereskedes.Models.SampleData.Cars().List(depos);

public List<Car> List(IEnumerable<Depo> depos)
{
    // now you have depos to look for id's in
    return new List<Car>
    {
        new Car {
            CarId = Guid.NewGuid(),
            DepoId = depos.SingleOrDefault(x => [your predicate]),
        },
        new Car {
        }
    };
}

OTHER TIPS

The process is called "seeding" the data.

You create an initializer object and override the Seed method:

public class MyDataContextDbInitializer : DropCreateDatabaseIfModelChanges<MyDataContext>
{
   protected override void Seed(MagazineContext context)
   {
     context.Customers.Add(new Customer() { CustomerName = "Test Customer" });
   }
} 

Here is an article describing how to do it: http://www.codeproject.com/Articles/315708/Entity-Framework-Code-First-Data-Initializers

I made an Nuget package, so you can generate random contact data (firstname, lastname, city, zipcode, birthdates, accountnumbers, etc)

In this version you can export to CSV, XML, JSON and SQL.

Open Visual Studio, Manage Nuget Packages Search online for:

DSharp FrameWork: ContactGenerator

Any suggestions for extending functionality are welcome.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top