Domanda

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.

È stato utile?

Soluzione

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

U need to save data here.

    dbContext.SaveChanges();

    dbContext.Entry(dog).Reload();

    return dog.Id;
}

Altri suggerimenti

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

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top