Sfmar
Sfmar

Reputation: 159

Seed One-to-one Relationship ASP .NET MVC

I am building a web application using ASP .NET MVC5 and EF6.

I am trying to seed data to a one-to-one-relationship defined as such:

Models

public class Client 
{
  public int ClientId { get; set; }  
  [Required]
  public string Name { get; set; }

  public Address Address { get; set; }
}

public class Address 
{
  [ForeignKey("Client")]
  public int AddressId { get; set; }  
  [Required]
  public string StreetName { get; set; }

  public Client Client { get; set; }
}

Where Address is the dependent end.

Now, I want to seed these two tables using EF and in /Migrations/Configuration.cs I added the following code:

internal sealed class Configuration : DbMigrationsConfiguration<MR_TrackTrace.Models.ApplicationDbContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(MR_TrackTrace.Models.ApplicationDbContext context)
        {

            var clients = new List<Client>
            {
                new Client { Name = "John" },
                new Client { Name = "Mary" },
                new Client { Name = "Philip" }
            };

            clients.ForEach(s => context.Clients.AddOrUpdate(p => p.Name, s));

            context.SaveChanges();
            var addresses = new List<Address>
            {
                new Address { StreetName = "something", Client = clients.FirstOrDefault(s => s.Name == "John") },
                new Address { StreetName = "other", Client = clients.FirstOrDefault(s => s.Name == "Philip") },
                new Address { StreetName = "another", Client = clients.FirstOrDefault(s => s.Name == "Mary") }
            };

            addresses.ForEach(s => context.Addresses.AddOrUpdate(p => p.Name, s));
            context.SaveChanges();
        }
 }

Now, after adding the migration and updating the database, I checked the tables and the Client is built and seeded according but the Address table has a column named ClientId as expected because it is the Foreign Key.

But this column is not filled with the expected ID, instead it is filled with "0". By using:

Client = clients.FirstOrDefault(s => s.Name == "John")

I was expecting that the context would automatically set the ClientId for this table.

Can anyone help me guiding me through this issue? Thanks in advance!

Upvotes: 0

Views: 925

Answers (2)

Sfmar
Sfmar

Reputation: 159

Solved my problem by seeding as follows:

 protected override void Seed(MR_TrackTrace.Models.ApplicationDbContext context)
        {

            var clients = new List<Client>
            {
                new Client { Name = "John" },
                new Client { Name = "Mary" },
                new Client { Name = "Philip" }
            };

            clients.ForEach(s => context.Clients.AddOrUpdate(p => p.Name, s));

            context.SaveChanges();
            var addresses = new List<Address>
            {
                new Address { StreetName = "something", ClientId = context.Clients.FirstOrDefault(s => s.Name == "John").ClientId },
                new Address { StreetName = "other", ClientId = context.Clients.FirstOrDefault(s => s.Name == "Philip").ClientId },
                new Address { StreetName = "another", ClientId = context.Clients.FirstOrDefault(s => s.Name == "Mary").ClientId }
            };

            addresses.ForEach(s => context.Addresses.AddOrUpdate(p => p.Name, s));
            context.SaveChanges();
        }

Still don't know why EF was not able to link the two tables and automatically fill the ClientId in the Address table.

Thanks!

Upvotes: 1

Alex Grogan
Alex Grogan

Reputation: 168

Are you not able to add the address like this:

var clients = new List<Client>
{
    new Client { Name = "John", Address = new Address() { StreetName = "Something" } },
    new Client { Name = "Mary", Address = new Address() { StreetName = "Other" }  },
    new Client { Name = "Philip", Address = new Address() { StreetName = "Another" }  }
};

When it save changes, it should create the client and address at the same time and link them together

Upvotes: 0

Related Questions