web-dev-qa-db-fra.com

Entity Framework Code First Lazy Loading

J'ai deux classes d'objets

public class User
{
    public Guid Id { get; set; }
    public string Name { get; set; }

    // Navigation
    public ICollection<Product> Products { get; set; }
}

public class Product
{
    public Guid Id { get; set; }

    // Navigation
    public User User { get; set; }
    public Guid User_Id { get; set; }

    public string Name { get; set; }
}

Lorsque je charge un utilisateur à l'aide de dataContext, j'obtiens la liste des produits étant nulle (c'est ok).

Si j'ajoute un mot clé "virtuel" à la liste des produits,

public virtual ICollection<Product> Products { get; set; }

lorsque je charge l'utilisateur, j'obtiens également la liste des produits.

Pourquoi cela arrive-t-il? Je pensais que le mot clé "virtuel" est utilisé pour ne pas charger les entités, sauf si vous l'expliquez (en utilisant une instruction "Inclure")

Je pense que j'ai tout faux

30
Catalin

C'est faux

Le mot clé "virtuel" est utilisé pour ne pas charger les entités sauf si vous l'expliquez (en utilisant une instruction "Inclure")

Le chargement différé signifie que les entités seront automatiquement chargées lors de votre premier accès à la propriété de collection ou de navigation, et cela se produira de manière transparente, comme si elles étaient toujours chargées avec l'objet parent.

L'utilisation de "include" se charge à la demande, lorsque vous spécifiez les propriétés que vous souhaitez interroger.

L'existence du mot clé virtual n'est liée qu'au chargement différé. virtual Le mot clé permet au runtime du framework d'entité de créer des proxys dynamiques pour vos classes d'entité et leurs propriétés, et par conséquent, de prendre en charge le chargement différé. Sans chargement virtuel, le chargement paresseux ne sera pas pris en charge et vous obtenez null sur les propriétés de la collection.

Le fait est que vous pouvez utiliser "include" dans tous les cas, mais sans chargement paresseux, c'est le seul moyen d'accéder aux propriétés de collection et de navigation.

66
archil

Je suppose que vous recherchez une propriété qui fait l'objet d'une charge paresseuse tout en étant dans le contexte ef:

using (var db = new Context())
{
    var user = db.Users.Where(...);

    var products = user.Products; // being loaded right away
}

Essayez de le laisser:

User user;
using (var db = new Context())
{
    user = db.Users.Where(...);

    // I guess you will need here:
    // .Include(u => u.Products)
}
var products = user.Products; // what error will you get here?
4
abatishchev