1

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;
}

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

Comments

1

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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.