This is my first time using Entity Framework 6.1 (code first). I keep running into a problem where my navigation properties are null when I don't expect them to be. I've enabled lazy loading.
My entity looks like this:
public class Ask
{
    public Ask()
    {
        this.quantity = -1;
        this.price = -1;
    }
    public int id { get; set; }
    public int quantity { get; set; }
    public float price { get; set; }
    public int sellerId { get; set; }
    public virtual User seller { get; set; }
    public int itemId { get; set; }
    public virtual Item item { get; set; }
}
It has the following mapper:
class AskMapper : EntityTypeConfiguration<Ask>
{
    public AskMapper()
    {
        this.ToTable("Asks");
        this.HasKey(a => a.id);
        this.Property(a => a.id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        this.Property(a => a.id).IsRequired();
        this.Property(a => a.quantity).IsRequired();
        this.Property(a => a.price).IsRequired();
        this.Property(a => a.sellerId).IsRequired();
        this.HasRequired(a => a.seller).WithMany(u => u.asks).HasForeignKey(a => a.sellerId).WillCascadeOnDelete(true);
        this.Property(a => a.itemId).IsRequired();
        this.HasRequired(a => a.item).WithMany(i => i.asks).HasForeignKey(a => a.itemId).WillCascadeOnDelete(true);
    }
}
Specifically, the problem is that I have an Ask object with a correctly set itemId (which does correspond to an Item in the database), but the navigation property item is null, and as a result I end up getting a NullReferenceException. The exception is thrown in the code below, when I try to access a.item.name:
List<Ask> asks = repo.GetAsksBySeller(userId).ToList();
List<ReducedAsk> reducedAsks = new List<ReducedAsk>();
foreach (Ask a in asks)
{
    ReducedAsk r = new ReducedAsk() { id = a.id, sellerName = a.seller.username, itemId = a.itemId, itemName = a.item.name, price = a.price, quantity = a.quantity };
    reducedAsks.Add(r);
}
Confusingly, the seller navigation property is working fine there, and I can't find anything I've done differently in the 'User' entity, nor in its mapper.
I have a test which recreates this, but it passes without any problems:
public void canGetAsk()
{
    int quantity = 2;
    int price = 10;
    //add a seller
    User seller = new User() { username = "ted" };
    Assert.IsNotNull(seller);
    int sellerId = repo.InsertUser(seller);
    Assert.AreNotEqual(-1, sellerId);
    //add an item
    Item item = new Item() { name = "fanta" };
    Assert.IsNotNull(item);
    int itemId = repo.InsertItem(item);
    Assert.AreNotEqual(-1, itemId);
    bool success = repo.AddInventory(sellerId, itemId, quantity);
    Assert.AreNotEqual(-1, success);
    //add an ask
    int askId = repo.InsertAsk(new Ask() { sellerId = sellerId, itemId = itemId, quantity = quantity, price = price });
    Assert.AreNotEqual(-1, askId);
    //retrieve the ask
    Ask ask = repo.GetAsk(askId);
    Assert.IsNotNull(ask);
    //check the ask info
    Assert.AreEqual(quantity, ask.quantity);
    Assert.AreEqual(price, ask.price);
    Assert.AreEqual(sellerId, ask.sellerId);
    Assert.AreEqual(sellerId, ask.seller.id);
    Assert.AreEqual(itemId, ask.itemId);
    Assert.AreEqual(itemId, ask.item.id);
    Assert.AreEqual("fanta", ask.item.name);
}
Any help would be extremely appreciated; this has been driving me crazy for days.
EDIT:
The database is SQL Server 2014.
At the moment, I have one shared context, instantiated the level above this (my repository layer for the db). Should I be instantiating a new context for each method? Or instantiating one at the lowest possible level (i.e. for every db access)? For example:
public IQueryable<Ask> GetAsksBySeller(int sellerId)
{
    using (MarketContext _ctx = new MarketContext())
    {
        return _ctx.Asks.Where(s => s.seller.id == sellerId).AsQueryable();
    }
}
Some of my methods invoke others in the repo layer. Would it better for each method to take a context, which it can then pass to any methods it calls?
public IQueryable<Transaction> GetTransactionsByUser(MarketContext _ctx, int userId)
{
    IQueryable<Transaction> buyTransactions = GetTransactionsByBuyer(_ctx, userId);
    IQueryable<Transaction> sellTransactions = GetTransactionsBySeller(_ctx, userId);
    return buyTransactions.Concat(sellTransactions);
}
Then I could just instantiate a new context whenever I call anything from the repo layer: repo.GetTransactionsByUser(new MarketContext(), userId);
Again, thanks for the help. I'm new to this, and don't know which approach would be best.
                        
Try to add Include call in your repository call:
Also, there is an extension method Include which accepts lambda expression as parameter and provides you type checks on compile time
http://msdn.microsoft.com/en-us/data/jj574232.aspx