I'm having huge difficulties getting my navigation properties to work in EF Code First. As an abstracted example, I have:
public class Parent{
public int ParentID {get; set;}
public virtual List<NamedChild> Children {get; set;}
public Parent(){}
public void Init(int ParentID, List<UnnamedChild> Children){
this.ParentID = ParentID;
this.Children = Children.ConvertAll(x => new NamedChild(x, ""));
}
}
public class NamedChild{
public int ChildID {get; set;}
public string Name {get; set;}
public NamedChild(UnnamedChild c, string Name){
this.ChildID = c.ChildID;
this.Name = Name;
}
}
public class UnnamedChild{
public int ChildID {get; set;}
public UnnamedChild(int ChildID){
this.ChildID = ChildID;
}
}
and then later...
List<UnnamedChild> children = GetChildrenFromSomewhere();
Parent p = db.Parents.Create();
p.Init(1, children);
db.Parents.Add(p);
db.SaveChanges();
Now if I'm debugging I can look into the current DbSet and it shows that there is 1 Parent, and its "Children" property is set to a List of 2 NamedChild. This is good, this is what it should be. However, if I stop the program and re-run it, when I look in the DbSet there is still 1 Parent, but its "Children" property has been set to null.
In summary, immediately after saving it the values are right, but as soon as I re-load the DB Context those values are missing (nulls). I am running the most recent EF with LazyLoading enabled.
It should be noted that if I use .Include(), it will populate those null values with the proper NamedChild list, but I need this to work with LazyLoading.
Although I don't think it should technically matter, I've noticed that EF seems to prefer ICollections
to other list/array types. Try:
public virtual ICollection<NamedChild> Children {get; set;}
Also, I'm a little confused about what you're trying to achieve with your custom constructors. It seems that all you're doing is initializing the properties on the instance. If that's the case, a custom constructor is not needed. Just use the class initialization syntax:
x => new NamedChild { ChildId = x.ChildId, Name = "" }
I think EF is probably unable to create a proxy for NamedChild
objects, and can't perform any lazy loading as a result.
One of the requirements for creating a proxy class is that your POCO must have a public/protected
constructor without parameters.
This may solve your problem:
public class NamedChild
{
public int ChildID {get; set;}
public string Name {get; set;}
protected NamedChild() {}
public NamedChild(UnnamedChild c, string Name)
{
this.ChildID = c.ChildID;
this.Name = Name;
}
}
I believe you already meet all the other requirements for lazy loading proxies.
Full Requirements here: http://msdn.microsoft.com/en-us/library/vstudio/dd468057%28v=vs.100%29.aspx
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.