除非调用ToList,否则不包括导航属性

时间:2015-09-04 16:14:43

标签: c# entity-framework-core

我使用的是EF7 beta 7.我有几个论坛样式表,它们之间有导航属性,以及在上下文的OnModelCreating方法中设置的关系:

public class Forum
{
    public int ForumId { get; set; }
    public string Title { get; set; }

    public ICollection<Topic> Topics { get; set; } =  new List<Topic>();
}

public class Topic
{
    public int TopicId { get; set; }
    public string Title { get; set; }

    public int ForumId { get; set; }
    public Forum Forum { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<Forum> Forums { get; set; }
    public DbSet<Topic> Topics { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Forum>()
                    .Collection(f => f.Topics)
                    .InverseReference(t => t.Forum)
                    .ForeignKey(t => t.ForumId);
    }
}

我试图获取Forum的清单Topic

var forums = _context.Forums.Include(f => f.Topics)
                            .Select(f => new 
                                {
                                    f.Title,
                                    f.ForumId,
                                    f.Topics.Count
                                });

当我按原样运行时,我得到一个ArgumentNullException 我得到一个空集合,因为它似乎并没有真正急切地加载Topic。我已检入Sql Profiler并确认其仅运行选择以获取Forum并且没有第二次选择Topic&#39; s

如果我在ToList之前致电Select

var forums = _context.Forums.Include(f => f.Topics)
                            .ToList()
                            .Select(f => new 
                                {
                                    f.Title,
                                    f.ForumId,
                                    f.Topics.Count
                                });

它将包含Topic和代码运行,但是这会使目的失败,因为这会导致它枚举包含所有主题的所有论坛,而然后计数在数据库上运行Count。这是Include的错误,还是我使用Include错误?

1 个答案:

答案 0 :(得分:1)

您需要配置主题和论坛之间的关系才能使.Include生效。

class YourContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
          // configure the relationship here
    }
}

有关使用集合的更多提示,请参阅How to work with collections

另一个注释

.ToList()之后立即致电.Include(...),您正在强制进行早期评估。 .Select(...)中的以下投影在客户端内存中运行,而不是使用EF7的查询管道。

另外,请确保在POCO定义中添加初始化程序。

public ICollection<Topic> Topics { get; set; } = new List<Topic>()