I've been using EF Code First for awhile but this is my first time with EF7.
I have the following Model classes where Venue has a one-to-many relationship to Show:
public class Show
{
public int Id { get; set; }
public Venue Venue { get; set; }
//...
}
public class Venue
{
public int Id { get; set; }
public string Name {get; set; }
//...
public List<Show> Shows { get; set; }
}
I set up the DBContext like this:
public class NettlesContext : DbContext
{
public DbSet<Show> Shows { get; set; }
public DbSet<Venue> Venues { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
new ShowConfiguration(builder.Entity<Show>());
new ImageConfiguration(builder.Entity<Image>());
}
}
public class ShowConfiguration
{
public ShowConfiguration(EntityTypeBuilder<Show> builder)
{
builder.Property(p => p.Id).IsRequired();
builder.Property(p => p.Title).IsRequired();
}
}
public class VenueConfiguration
{
public VenueConfiguration(EntityTypeBuilder<Venue> builder)
{
builder.Property(p => p.Id).IsRequired();
builder.Property(p => p.Name).IsRequired();
}
}
Then in some start up code I initialize the database like this:
private static void AddShows(NettlesContext db)
{
var shows = new List<Show>()
{
new Show()
{
Title = "Portland Country Dance Community Contra Dance",
Venue = new Venue()
{
Name = "Fulton Community Center",
},
},
new Show()
{
Title = "Portland Roadhouse Contra Dance",
Venue = new Venue()
{
Name = "Milwaukie Community Club",
},
},
};
db.Shows.AddRange(shows);
db.SaveChanges();
}
The Shows table is properly initialized except that the VenueId is null. The Venue table is entirely empty.
What's going on?
There is a second argument to DbSet.Add
.
Add(TEntity entity, GraphBehavior behavior = GraphBehavior.IncludeDependents)
Although the default is to IncludeDependents
(aka children entities), EF7's behavior of Add()
is not identifying Venue
as a child of Show
. In your OnModelCreating
you need to specify the relationship between Venue
and Show
. See Relationships in the EF7 Docs.
Example:
modelBuilder.Entity<Venue>(entityBuilder =>
{
entityBuilder
.HasMany(v => v.Shows)
.WithOne(s => s.Venue)
.HasForeignKey(s => s.VenueId);
});
Even with this however, you will still need to call .Add on the new instances of Venue because Show is not a dependent (child) of Venue.
private static void AddShows(NettlesContext db)
{
var fulton = new Venue()
{
Name = "Fulton Community Center",
};
var club = new Venue()
{
Name = "Milwaukie Community Club",
};
db.Venues.Add(fulton);
db.Venues.Add(club);
var shows = new List<Show>()
{
new Show()
{
Title = "Portland Country Dance Community Contra Dance",
Venue = fulton,
},
new Show()
{
Title = "Portland Roadhouse Contra Dance",
Venue = club
},
};
context.Shows.AddRange(shows);
}
Worth noting: this behavior of .Add() has been a source of confusion in EF7 RC1 and its behavior may be changing in EF7 RC2. See https://github.com/aspnet/EntityFramework/pull/4132
You need to update your model as this
public class Venue
{
public int Id { get; set; }
public string Name {get; set; }
//...
public List<Show> Shows { get; set; }
}
public class Show
{
public int Id { get; set; }
public int VenueId { get; set; }
[ForeignKey("VenueId")]
public Venue Venue { get; set; }
//...
}
ForegnKey attribute is used to define the foriegn key of the relation between two tables