与“非虚拟"问题有关. ICollections [英] Problem with "non virtual" ICollections

查看:102
本文介绍了与“非虚拟"问题有关. ICollections的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好.我正在与Entity Framework进行一些讨论,但他不想接受失败!所以我会寻求帮助.


我将使用两个简单的实体作为示例:

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:

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:

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);
        }



如果我尝试以任何方式访问子级的Icollection,它将为我提供null引用异常.如果在父"类定义中,我将ICollection< child>设置为到虚拟,一切正常.

我在创建子代之前尝试将子代添加到父代时遇到了类似的问题.我认为,如果从数据库中进行拾取,则ICollection将充满相应的子代.

如果我没看错,那么virtual关键字应该只为指定实体启用lazyload;删除虚拟,从数据库中选择父对象时,EF是否不应该自动加载子对象?是否必须指定要同时加载子项和父项?

预先谢谢你,

Alberto



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

推荐答案

您错了.除非进行编程,否则Virtual不允许延迟加载或类似的加载.对于getter和setter,仅虚拟更改调用分派到通常的OOP动态分派(认为是虚拟方法表)(还有getter或setter的语法).这仅使派生类可以覆盖getter或setter.就像您的情况一样,它不会影响没有层次结构的代码中的行为(性能略有降低的除外).

因此,我认为您的观察是不正确的.您可能修改了其他内容.错误的实验是很平常的事情.引发异常是因为您没有为属性children分配任何内容.

如果需要,可以制作一个带有两种情况的 complete 代码示例并将其发布.我一定会解释为什么它会以这种方式或其他方式起作用.

—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


似乎我找到了解决方案(或者至少看起来如此):

通过使用virtual,可以告诉Entity Framework启用指定属性的延迟加载.

问题是我误解了非虚拟集合(或单个实体)的紧急加载策略:我认为它将自动紧急加载",而紧急加载必须使用 include 明确地完成:

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:

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

ViewBag.childrenCount = parent.children.Count;

return(loadedParent);



请注意,可以手动关闭惰性加载,并且我还阅读到在某些情况下,EF会自动将其关闭(如果我没记错,例如在模型验证期间进行验证).



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).


这篇关于与“非虚拟"问题有关. ICollections的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆