简体   繁体   English

实体框架 - 导航属性不保存

[英]Entity Framework - Navigation Properties Not Saving

I'm having huge difficulties getting my navigation properties to work in EF Code First. 我的导航属性在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. 现在,如果我正在调试,我可以查看当前的DbSet,它显示有1个Parent,其“Children”属性设置为2 NamedChild的List。 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. 但是,如果我停止程序并重新运行它,当我查看DbSet时,仍然有1个Parent,但其“Children”属性已设置为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. 我正在运行最新的EF并启用了LazyLoading。

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. 应该注意的是,如果我使用.Include(),它将使用正确的NamedChild列表填充这些空值,但我需要使用它来使用LazyLoading。

Although I don't think it should technically matter, I've noticed that EF seems to prefer ICollections to other list/array types. 虽然我认为它在技术上不重要,但我注意到EF似乎更喜欢ICollections到其他列表/数组类型。 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. 我认为EF可能无法为NamedChild对象创建代理,因此无法执行任何延迟加载。

One of the requirements for creating a proxy class is that your POCO must have a public/protected constructor without parameters. 创建代理类的一个要求是您的POCO必须具有不带参数的public/protected构造函数。

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 完整要求: http//msdn.microsoft.com/en-us/library/vstudio/dd468057%28v=vs.100%29.aspx

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

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