2

This is my first code-first project and have never had an issue doing this in db-first, that I can remember. So, I'm either missing something obvious or there's a rule I missed somewhere. I do not want to use lazy loading, and have to think that it's not required to do this, given the many examples using eager loading.

Very simple. Parent record is Listing, child records are Bid entities:

public class Listing {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ListingID { get; set; }

    [Required]
    [StringLength(140)]
    public string Title { get; set; }

    //...etc.

    public List<Bid> Bids { get; set; }

    public Listing() {
        Bids = new List<Bid>();
    }
}

public class Bid {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int BidID { get; set; }

    [Required]
    public decimal Amount { get; set; }

    //...etc.

    public int ListingID { get; set; }

    [ForeignKey("ListingID")]
    public Listing Listing { get; set; }

    public Bid() {
        Listing = new Listing();
    }
}

I'm using Include to pull the child records:

        using (var db = new MyDbContext()) {
            var listing = db.Listings
                .Where(x => x.Active == true && x.UserID == "abc123")
                .Include(x => x.Bids)
                .FirstOrDefault();
        }

Child collection exists but is always empty (Count = 0) - it's not pulling the records. They're definitely in the tables. I can manually query this and get those bid records, no problem. Basically, I need a listing and all of its bids, similar to this:

select l.*, b.*
from Listing l
inner join Bid b on l.ListingID = b.ListingID
where l.Active = 1
and l.UserID = 'abc123'

What's missing? This article says I'm doing it right:

https://msdn.microsoft.com/en-us/data/jj574232.aspx

Tsar Bomba
  • 1,047
  • 6
  • 29
  • 52
  • I've always used virtual collections in this scenario; so in my `Listing` class I would have `public virtual ICollection Bids { get; set; }`. I don't know if that's what's causing your issue. Could be a mapping issue as well. – drneel Mar 16 '16 at 15:13
  • 2
    See Gert's answer here: http://stackoverflow.com/questions/20757594/ef-codefirst-whether-initialize-navigation-properties – Steve Greene Mar 16 '16 at 15:22
  • @drneel - Thanks, but do not want to use lazy loading for this. – Tsar Bomba Mar 16 '16 at 15:57
  • @SteveGreene - That is to say, it can't be done? How would I define foreign key relationships in my model, in code first, without assigning the collection in the constructor? I'm scouring old code to see examples of where I've maybe done this before...seems hard to believe. – Tsar Bomba Mar 16 '16 at 20:31

2 Answers2

1

Figured it out. I KNEW I had done this type of relationship before. I found an older project where I did the exact same thing. All I had to do was remove the constructor in the Bid class. Apparently it goes awry if you specify both sides of the relationship? I don't know...but now it works and it's pulling the expected records. Frustrating! Seems like they could add some validation to help you from shooting yourself in the foot, so easily. If it's not valid, it'd be nice to know for certain.

Everything the same as the OP, save for this class:

public class Bid {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int BidID { get; set; }

    [Required]
    public decimal Amount { get; set; }

    //...etc.

    public int ListingID { get; set; }

    [ForeignKey("ListingID")]
    public Listing Listing { get; set; }

    //public Bid() {
    //    Listing = new Listing();
    //}
}
Tsar Bomba
  • 1,047
  • 6
  • 29
  • 52
0

Try with removing the constructor for both classes.

  • Thanks, but do not want to use lazy loading for this. – Tsar Bomba Mar 16 '16 at 15:57
  • I didn't ask to go with lazy loading even. By default it is enabled , you disable it and try – Nithila Shanmugananthan Mar 16 '16 at 16:08
  • Disabled lazy loading in the DbContext class, and it didn't change anything. Still loading an empty collection. – Tsar Bomba Mar 16 '16 at 18:43
  • Yes, this doesn't work. Appreciate the effort, but using "virtual" on the properties is associated purely with lazy loading, from everything I've read. Even with lazy loading explicitly disabled and virtual on the properties on both entities, nothing changes. Bids Count is still zero. – Tsar Bomba Mar 16 '16 at 20:29
  • Try with, Get off the constructor for those two classes.it is not necessary – Nithila Shanmugananthan Mar 16 '16 at 21:08
  • The documentation for EF 6.x suggests that initializing the list in the constructor, for the children, is how you establish the FK relationship. It works this way, also, if you take a look at the answer I posted. I *did* need to remove it from the child side of the relationship. – Tsar Bomba Mar 16 '16 at 21:26