Reputation: 59
I've seen many questions on this being asked but I can't find one that helps me, I trying to create a one to many relation between buildings and rooms i.e one building with many rooms. As far as I can tell my ICollection<> value isn't being sent to my database. I'm using a partial view to create rooms inside of a building, my buildings model contains the Icollection and my rooms model contains the building Id. However when I create a room it doesn't connect the buildingId with the ICollection<> value.
Here are my models for both the buildings and the rooms:
public class buildingInfo
{
public int Id { get; set; }
public int buildingNumber { get; set; }
public String buildingName { get; set; }
public String buildingAddress { get; set; }
public String buildingDesc { get; set; }
public virtual ICollection<roomInfo> curRooms { get; set; }
}
public class roomInfo
{
public int Id { get; set; }
public int roomNumber { get; set; }
public String roomName { get; set; }
public String roomLocation { get; set; }
public String roomDesc { get; set; }
public int buildingId { get; set; }
}
This the rooms view:
@model TerminalHost.Models.buildingInfo
@{
ViewBag.Title = "Home Page";
}
<h3>Rooms in: @Model.buildingName</h3>
<ol class="round">
<li class="one">
<h5>Please begin creating your network structure:</h5> <button id="modal-opener">Add a new room</button>
</li>
</ol>
@Html.Partial("rooms", Model.curRooms)
<div id="Modal" title="Room Details">
@Html.Partial("roomForm", new TerminalHost.Models.roomInfo { buildingId = Model.Id })
</div>
Here is the form that takes in the room details:
@model TerminalHost.Models.roomInfo
<h2>Create</h2>
@using (Html.BeginForm("roomForm","Home"))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>roomInfo</legend>
<div class="editor-label">
@Html.Label("Room Number:")
</div>
<div class="editor-field">
@Html.EditorFor(model => model.roomNumber)
@Html.ValidationMessageFor(model => model.roomNumber)
</div>
....
<div style="visibility: hidden">
<div class="editor-field">
@Html.TextBoxFor(model => model.buildingId)
@Html.ValidationMessageFor(model => model.buildingId)
</div>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
And these are the methods handling the rooms partial view:
[HttpGet]
public ActionResult roomForm(int buildingId)
{
return PartialView();
}
//Here the data from the room form is inserted to the database
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult roomForm(roomInfo roominfo)
{
//roominfo.
if (ModelState.IsValid)
{
_db.rooms.Add(roominfo);
_db.SaveChanges();
return RedirectToAction("room", new {id = roominfo.buildingId});
}
return PartialView(roominfo);
}
Here is the DBContext:
public class thDB : DbContext
{
public DbSet<buildingInfo> buildings { get; set; }
public DbSet<roomInfo> rooms { get; set; }
public DbSet<deviceInfo> devices { get; set; }
public DbSet<rackInfo> rackInfoes { get; set; }
}
If any further info is required please ask.
Upvotes: 0
Views: 105
Reputation: 9411
Hope this helps
public class buildingInfo
{
public buildingInfo()
{
curRooms = new List<roomInfo>();
}
[Key]
public int Id { get; set; }
public int buildingNumber { get; set; }
public String buildingName { get; set; }
public String buildingAddress { get; set; }
public String buildingDesc { get; set; }
public virtual ICollection<roomInfo> curRooms { get; set; }
}
public class roomInfo
{
public roomInfo()
{
}
[Key]
public int Id { get; set; }
public int roomNumber { get; set; }
public String roomName { get; set; }
public String roomLocation { get; set; }
public String roomDesc { get; set; }
public virtual buildingInfo BuildingInfo { get; set; }
}
Upvotes: 0
Reputation: 7066
I think Entity Framework cannot identify the correct foreign key between your entities by its conventions because your property naming conventions do not match anything EF expects. Likely it's adding its own foreign key so when you set buildingId on the roomInfo entity it isn't being treated as a foreign key.
You can try adding some entity mapping configuration in your DbContext to explicitly describe the relationship:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<buildingInfo>().HasMany(b=>b.curRooms).WithRequired().HasForeignKey(r=>r.buildingId);
}
Upvotes: 1