简体   繁体   English

使用实体框架的可能的延迟加载条件

[英]Possible Lazy Loading Condition Using Entity Framework

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. 我遇到的问题是当我添加一条新狗,然后尝试像这样访问“ Puppies”导航属性时。

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. 当我访问导航属性“ dog.Puppies”时,它为空。 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? 要使“ puppies”导航属性填充数据而不是使用“ GetPuppies()”方法,该怎么办? 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. 我不知道这是否是延迟加载条件,但是在所有其他代码中,“ puppies”导航属性都包含数据。 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. 这里有一个可能的解决方案 ,但我宁愿不必手动加载导航属性。

In your getdog method, put in an include(x=> x.puppies).find(... 在您的getdog方法中,放入一个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 可以通过dbcontext对象上的设置参数轻松打开/关闭延迟加载

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

U need to save data here. 您需要在此处保存数据。

    dbContext.SaveChanges();

    dbContext.Entry(dog).Reload();

    return dog.Id;
}

After some time playing around with this, I figured out what was wrong. 经过一段时间的研究,我发现了哪里出了问题。 I wasn't updating the dogId on each puppy. 我没有更新每只小狗的dogId。 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM