So I am trying out Entity Framework Core, and am having trouble with my first pair of relational Models. I'm trying to use conventions to form the relationship, as follows:
The principal entity, with conventional principal key (Id) and collection navigation property (the list of Locations):
public class Site
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public int LocationCount { get; set; } = 1;
public List<Location> Locations { get; set; } = new List<Location>();
}
The dependent entity, with conventional foreign key (SiteId) and reference navigation property (Site):
public class Location
{
public int Id { get; set; }
public int SiteId { get; set; }
public Site Site { get; set; }
public int AreaCount { get; set; } = 1;
public Location(Site site) { SiteId = site.Id; }
}
And since I want every Site to already have at least one location, I put this in the Create action of the SiteController, in an attempt to create the dependents along with the principal:
[HttpPost]
public IActionResult Create(Site site)
{
_context.Sites.Add(site);
for (int i = 0; i < site.LocationCount; i++)
_context.Locations.Add(new Location(site));
_context.SaveChanges();
return RedirectToAction("Details", new { Name = site.Name });
}
However, on the Details view, when I try to display the Locations that were created, the list is always empty:
<h2>@Model.Locations.Count Locations</h2>
@foreach (Location l in Model.Locations)
{
<div class="row">
<div class="col-sm-12">@l.Id</div>
</div>
}
Just results in:
0 Locations
Thank you in advance for any help explaining what I've missed!
Edit: By request, here is the body of the Details action in the Site Controller, which gets the Model data for the Details View:
public IActionResult Details(string name)
{
var model = _context.Sites.FirstOrDefault(a => a.Name == name);
if (model == null) model = new Site();
return View(model);
}
Also, per one suggestion, I have fixed the problem of setting the Location.SiteId before Site.Id has a value, since the Id isn't automatically generated on the Site until after SaveChanges() is called. Unfortunately, the result (empty Locations list) is still the same:
[HttpPost]
public IActionResult Create(Site site)
{
int nextsiteid = _context.Sites.Count() + 1;
_context.Sites.Add(site);
for (int i = 0; i < site.LocationCount; i++)
_context.Locations.Add(new Location(siteid));
_context.SaveChanges();
return RedirectToAction("Details", new { Name = site.Name });
}
And changed the Location constructor to use the Id instead of the instance:
public Location(int siteid) { SiteId = siteid; }
Thanks in advance for any further suggestions!