Click here to Skip to main content
15,889,872 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi Everyone.. I'm having a little discussion with Entity Framework, but he doesn't want to accept defeat! So I'll ask for help..


I'll use two simple entities as example:

XML
public class parent{
    int parentid {get;set;}
    public ICollection<child> children{get; set;}
}

public class child{
    int childid{get;Set;}
    public virtual parent parent{get;set;}
}


now the following function:

C#
public ActionResult Edit(int id)
        {
            parent loadedParent = db.parent.Find(id);
            ViewBag.childrenCount = parent.children.Count; /*Example instruction that generates Null reference exception*/
            return(loadedParent);
        }


If I try to access, in any way, the Icollection of children, it gives me a null reference exception. If, in the "parent" class definition, I set the ICollection<child> to virtual, everything works fine.

I encountered a similar problem trying to add children to a parent before creating it.. I thought that, if picking up from the db, the ICollection would be filled with respective children.

If I'm not wrong, the virtual keyword should just enable lazyload for the specified entitites; removing virtual, shouldn't EF automatically load children when picking parent from db? do I have to specify that I want to load also the children along with the parent?

thank you in advance,

Alberto
Posted
Updated 23-Dec-11 5:14am
v4
Comments
Sergey Alexandrovich Kryukov 5-Dec-11 14:31pm    
Please add the tags ".NET" and "C#" and remove two other tags, they are irrelevant.
--SA

You are wrong. Virtual does not allow lazy load or anything like that unless you program it. Virtual only change call dispatching to the usual OOP dynamic dispatch (think virtual method table) for getters and setters (there is also the syntax for getter or setter only). This just enables the derived class to override getter or setter. It cannot effect behavior (except slightly lower performance) in code without hierarchy, as in your case.

Therefore, I don't think your observation is correct. You probably modified something else. Incorrect experiments is a usual thing. Your exception is thrown just because you did not assign anything to the property children.

If you want, you can make a complete code sample with two cases and post it. I will certainly explain why it works in this or another way.

—SA
 
Share this answer
 
It seems like I found the solution (or at least it seems to):

by using virtual, you can tell to Entity Framework to enable lazy loading of specified property.

The problem was that I misunderstood the eager load policies of a non Virtual collection (or single entity): I thought that it would be "eager loaded" automatically, while eager load must be done explicitly using include:

C#
parent loadedParent = db.parent.include("children").FirstOrDefault(m=>m.parentid == id);

ViewBag.childrenCount = parent.children.Count;

return(loadedParent);


Note that lazy loading may be manually turned off, and I have also read that in some cases EF will turn out it automatically (IF I'm not wrong, for examplte during model validation).
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900