0

I'm running into what I believe is an issue with lazy loading in the Entity Framework. Suppose I have the following database-first entities and code.

public partial class Dog
{
    // This is the primary key in the database table.
    public int Id { get; set; }

    public string Name { get; set; }
    public virtual ICollection<Puppy> Puppies { get; set; }
}

public partial class Puppy
{
    // This is the primary key in the database table.
    public int Id { get; set; }

    // This is a foreign key in the database. This maps to Dog.Id.
    public int DogId { get; set; }

    public string Name { get; set; }
}

public Dog GetDog(int dogId)
{
    return = dbContext.Dogs.Find(dogId);
}

public List<Puppy> GetPuppies(int dogId)
{
    return = dbContext.Puppies.Where(p => p.DogId == dogId).ToList();
}

public int AddDog(Dog dog)
{
    dbContext.Dogs.Add(dog);
    dbContext.SaveChanges();
    dbContext.Entry(dog).Reload();
    return dog.Id;
}

public void AddPuppies(int dogId, List<Puppy> puppies)
{
    var dog = GetDog(dogId);
    dog.Puppies = puppies;
    dbContext.SaveChanges();
}

The problem I run into is when I add a new dog and then try to access the "Puppies" navigation property like so.

var dogId = AddDog(new Dog
{
    Name = "Fido"
});

AddPuppies(dogId, new List<Puppy>()
{
    new Puppy
    {
        Name = "Buddy"
    },
    new Puppy
    {
        Name = "Rex"
    },
});

var dog = GetDog(dogId);

foreach (var puppy in dog.Puppies)
{
    Console.WriteLine(puppy.Name);
}

When I access the navigation property "dog.Puppies", it's empty. However, if I run this code:

var puppies = GetPuppies(dogId);

foreach (var puppy in puppies)
{
    Console.WriteLine(puppy.Name);
}

then the "puppies" collection has data.

What must I do to get the "puppies" navigation property to populate with data instead of using the "GetPuppies()" method? I don't know if this is a lazy loading condition or not, but in all my other code the "puppies" navigation property has data. It's only when I add a new dog like this that the collection is empty. There is a possible solution here, but I'd rather not have to manually load the navigation properties.

1
  • Some things are not clear. You don't seem to associate the new Dog and the Puppies (dogId is not used). And it's not clear whether you call SaveChanges before GetPuppies. Commented Apr 18, 2014 at 22:05

3 Answers 3

0
public int AddDog(Dog dog)
{
    dbContext.Dogs.Add(dog);

U need to save data here.

    dbContext.SaveChanges();

    dbContext.Entry(dog).Reload();

    return dog.Id;
}
Sign up to request clarification or add additional context in comments.

Comments

0

In your getdog method, put in an include(x=> x.puppies).find(...

This will also enhance the performance, since everything gets built into the same query when executed. Lazyloading can easily be turned on/off by the setting params on your dbcontext object

Comments

0

After some time playing around with this, I figured out what was wrong. I wasn't updating the dogId on each puppy. Once I did that, it worked.

public int AddDog(Dog dog, List<int> puppyIds)
{
    dbContext.Dogs.Add(dog);
    dbContext.SaveChanges();
    dbContext.Entry(dog).Reload();

    foreach (var puppyId in puppyIds)
    {
        var puppy = dbContext.Puppies.Find(puppyId);
        puppy.DogId = dog.Id;
    }

    dbContext.SaveChanges();        
    return dog.Id;
}

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.