Trying to set up basic EF6 Optional 1:1. Extremely frustrating. I have read lots and lost of posts.
I have two entities, Guests and Seats, each one can exist on their own, a seat does not need a guest and a guest does not need a seat.
Guest Model:
public int ID { get; set; }
public int? SeatID { get; set; }
[Required]
public string FirstName { get; set; }
//Link to Seat
public Seat Seat { get; set; }
Seat Model:
public int ID { get; set; }
public int? GuestID { get; set; }
[Required]
public string SeatNumber { get; set; }
public bool Occupied { get { return (GuestID == null ? true : false); } }
//Link to Guest
public Guest Guest{ get; set; }
I had lots of problems just getting to this point. I had to add this to my model creation for the relationship to work:
modelBuilder.Entity<Seat>()
.HasOptional(g => g.Guest)
.WithOptionalDependent(s => s.Seat);
Now my application is working however when I try and load related data with the include method it just comes up blank, nothing there.
var seats = db.Seats.Include(s => s.Guest);
return View(seats.ToList());
On my view I use
@Html.DisplayFor(modelItem => item.Guest.FirstName)
I want to know how to make the include statement work, preferably without lazy loading (or even with if i have to). Also, I do not want to have a SeatAssignment table, I considered going down this road.
I could use a Viewmodel for this to work but i dont understand why the 1:1 optional is not loading the related data.
As requested, here is the generated schema...definitely something odd going on here. As a side note i can make it work with a viewmodel, but i dont want to.
1-0..1 relationship configuration is different from the way that you want.
Based on the above mentioned rules, your code should be as follows
Guest class
public class Guest
{
public int ID { get; set; }
[Required]
public string FirstName { get; set; }
public IList<Seat> Seats { get; set; }
}
Seat class
public class Seat
{
public int ID { get; set; }
[Required]
public string SeatNumber{ get; set; }
public IList<Guest> Guests { get; set; }
}
Join table
public GuestSeat
{
public int GuestID{get;set;}
public int SeatID{get;set;}
public DateTime ReservedDate{get;set;}
// other fields goes here
}
Configuration
modelBuilder.Entity<GuestSeat>()
.HasKey(gs => new {gs.GuestID,gs.SeatID})
.ToTable("GuestSeats");
modelBuilder.Entity<GuestSeat>()
.HasRequired(g=>g.Guest)
.WithMany(g=>g.Seats)
.HasForeignKey(gs =>gs.GuestID)
.DeleteOnCascade(false);
modelBuilder.Entity<GuestSeat>()
.HasRequired(s=>s.Seat)
.WithMany(s=>s.Guests)
.HasForeignKey(gs =>gs.SeatID)
.DeleteOnCascade(false);
This solution provide the following
SeatID
and ReservedDate
.Hope this will help you
You have to construct your models as shown below.
public class Guest
{
public int GuestId { get; set; }
[Required]
public string FirstName { get; set; }
//Link to Seat
public virtual Seat Seat { get; set; }
}
public class Seat
{
public int SeatId { get; set; }
[Required]
public string SeatNumber { get; set; }
public bool Occupied { get { return (GuestID == null ? true : false); }}
//Link to Guest
public virtual Guest Guest{ get; set; }
}
Fluent API mapping :
modelBuilder.Entity<Seat>()
.HasOptional(g => g.Guest)
.WithOptionalDependent(s => s.Seat);
Then :
var seats = db.Seats.Include(s => s.Guest).ToList();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.