实体框架中的实体关系代码优先

时间:2016-12-22 17:50:32

标签: entity-framework code-first

假设我有2个实体模型 -

public class Blog
{
    [Key]
    public int BlogId { get; set; }
    public string BlogName { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
}


public class Post
{
    [Key]
    public int PostId { get; set; }
    public string PostName { get; set; }
    public int BlogId { get; set; }

    [ForeignKey("BlogId")]
    public virtual Blog Blog { get; set; }
}

让我们来一个博客 -

var blog = dbContext.Blogs.Where(r => r.BlogId == 1).FirstOrDefault();

代码检索博客和所有帖子。但如果此博客下有数千个帖子?这将是一个性能问题。

默认情况下是否有任何不加载帖子的技巧?我不想从Posts删除Blog属性。

感谢。

2 个答案:

答案 0 :(得分:1)

您可以通过两种方式实现这一目标。

  1. 延迟加载
  2. 明确加载
  3. 延迟加载 - DbContext具有启用延迟加载DbContext.Configuration.LazyLoadingEnabled的配置设置。 默认情况下此设置为true,因此如果您未更改默认值,动态代理将执行延迟加载。对于使用延迟加载,需要在POCO类中实现两件事。

    1. 您的POCO课程必须是公开的而不是密封的。
    2. 您想要延迟加载的导航属性也必须标记为虚拟(您已经完成),以便Entity Framework可以覆盖属性以包含延迟加载逻辑。
    3. 2- 显式加载 - 显式加载类似于延迟加载,因为相关数据在加载主数据后单独加载。但是,与延迟加载不同,它不会自动发生;你需要调用一个方法来加载数据。

      使用DbContext.Entry方法实现显式加载。 Entry方法允许您访问DbContext关于实体的所有信息。这超出了存储在实际实体属性中的值,包括实体状态和从数据库中检索每个属性时的原始值。

      前:

      var blog = dbContext.Blogs.Where(r => r.BlogId == 1).FirstOrDefault();
      
      context.Entry(blog)
      .Collection(d => d.Posts)
      .Load();
      

答案 1 :(得分:0)

您可以使用projection

来控制加载哪些子项
var blogWithSomeChildren = dbContext.Blogs
                                    .Select(b => new
                                     {
                                         blog = b,
                                         selectedPosts = b.Posts.Where(p => p.PostId > 500) // or whatever criteria you want...
                                     })
                                    .Single(b => b.BlogId ==1);