首页 文章

虚拟关键字在Entity Framework 4.1 POCO Code First中有什么影响?

提问于
浏览
212

virtual 关键字在EF Code First中的属性上使用时是否有效?有人能描述不同情况下的所有后果吗?

例如,我知道它可以控制lazy loading - 如果你在ICollection / one-to-many关系属性上使用virtual关键字,默认情况下它将是延迟加载的,而如果你将虚拟关键字保留为out,它将是渴望加载 .

virtual 关键字在EF中与POCO实体有什么其他影响?我应该默认在我的所有属性上使用 virtual ,还是默认不使用它?

2 回答

  • 183

    到目前为止,我知道这些影响 .

    • Lazy Loading:任何 virtual ICollections都将延迟加载,除非您特别标记它们 .

    • More efficient change tracking . 如果您满足以下所有要求,那么您的更改跟踪可以通过挂钩您的虚拟属性来使用更有效的方法 . 从链接:

    要获取更改跟踪代理,基本规则是您的类必须是公共的,非抽象的或非密封的 . 您的类还必须为持久化的所有属性实现公共虚拟getter / setter . 最后,您必须仅将基于集合的关系导航属性声明为ICollection <T> . 它们不能是具体实现或从ICollection <T>派生的其他接口(与延迟加载代理的区别)

    描述这个的另一个有用的链接是MSDN的Requirements for Creating POCO Proxies .

  • 55

    此虚拟关键字与从实体框架加载数据的主题相关(延迟加载,急切加载和显式加载) .

    如果要使用延迟加载加载数据,则应使用 virtual 关键字 .

    lazy loading 是在第一次访问实体或实体集合时自动从数据库加载的过程 .

    例如,当使用下面定义的Blog实体类时,将在第一次访问Posts导航属性时加载相关的Posts:

    public class Blog 
    {  
         public int BlogId { get; set; }  
         public string Name { get; set; }  
         public string Url { get; set; }  
         public string Tags { get; set; }  
         public virtual ICollection<Post> Posts { get; set; }  
    }
    

    可以通过将Posts属性设置为非虚拟来关闭Posts集合的延迟加载 .

    如果延迟加载,则仍然可以使用预先加载(使用Include方法)或显式加载相关实体(使用Load方法)来实现Posts集合的加载 .

    急切地加载:

    using (var context = new BloggingContext()) 
    { 
        // Load all blogs and related posts 
        var blogs1 = context.Blogs 
                              .Include(b => b.Posts) 
                              .ToList(); 
    }
    

    明确加载:

    using (var context = new BloggingContext()) 
    { 
        var blog = context.Blogs.Find(1); 
    
        // Load the posts related to a given blog 
        context.Entry(blog).Collection(p => p.Posts).Load(); 
    }
    

相关问题