Reputation: 15872
I have a set of Entities:
public class Board : EntityBase
{
public ICollection<Slot> Slots { get; set; }
}
public class Slot : EntityBase
{
public ICollection<Card> Cards { get; set; }
public string Header { get; set; }
public int BoardId { get; set; }
}
public class Card : EntityBase
{
public string Description { get; set; }
public string Title { get; set; }
public int SlotId { get; set; }
}
And corresponding database tables:
CREATE TABLE Boards
(
Id INT PRIMARY KEY,
UserId INT NOT NULL,
CONSTRAINT FK_Users_UserId FOREIGN KEY (UserId)
REFERENCES Users(Id)
)
CREATE TABLE Slots
(
Id INT PRIMARY KEY,
Header NVARCHAR(MAX),
BoardId INT NOT NULL,
CONSTRAINT FK_Slots_BoardId FOREIGN KEY (BoardId)
REFERENCES Boards(Id)
)
CREATE TABLE Cards
(
Id INT PRIMARY KEY,
Title NVARCHAR(MAX),
Description NVARCHAR(MAX),
SlotId INT NOT NULL,
CONSTRAINT FK_Cards_SlotId FOREIGN KEY (SlotId)
REFERENCES Slots(Id)
)
When attempting retrieving and instantiate a 'Board' from the database it's not populating the 'Slots' property. It seems that Entity framework is unable to recognise that there's a foreign key constraint. My understanding is that if the properties are not virtual they will be eager loaded, please correct me if i'm wrong.
Is there something that I'm missing / need to setup to make navigation properties work?
The calling code:
Context.Boards.Find(id);
My DbContext:
public class SampleContext : DbContext, IUnitOfWork
{
public SampleContext() : base("name=SampleApplication") { }
public void Save()
{
SaveChanges();
}
public DbSet<Board> Boards { get; set; }
public DbSet<Card> Cards { get; set; }
public DbSet<Slot> Slots { get; set; }
}
I have made the navigation properties virtual and loaded as follows, this is now working:
public Board GetBoard(int id)
{
var board = Context.Boards.Find(id);
Context.Entry(board)
.Collection(b => b.Slots)
.Load();
return board;
}
Upvotes: 1
Views: 68
Reputation: 2442
Eager loading does not happen automatically like lazy loading does when you include the virtual keyword. You will need to use the Include() method
so something like
var graph = context.Boards.Include("Slots");
foreach(var board in graph)
{
Console.Writeline("Slot value {0}",board.Slots);
}
Upvotes: 1
Reputation: 9488
You must make navigation properties virtual
for EF proxy to be able to override it.
And you're wrong about non-virtual properties to be eager loaded. They do not. You must load them explicitly with Include
methods. Read here about it: https://msdn.microsoft.com/en-us/data/jj574232.aspx
Upvotes: 1