EF7核心多对多参考对象未填充

时间:2016-07-01 18:48:32

标签: entity-framework-core

我很难让EF7填充多对多连接中引用的对象。我在https://docs.efproject.net/en/latest/modeling/relationships.html跟踪了文档,但对象仍然是null。据我所知,你不必做任何具体的事情来让EF填充它们。我从文档页面复制了示例代码,如下所示:

public class MyContext : DbContext
{
    public DbSet<Post> Posts { get; set; }
    public DbSet<Tag> Tags { get; set; }

    public MyContext(DbContextOptions<MyContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<PostTag>()
            .HasKey(t => new { t.PostId, t.TagId });

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Post)
            .WithMany(p => p.PostTags)
            .HasForeignKey(pt => pt.PostId);

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Tag)
            .WithMany(t => t.PostTags)
            .HasForeignKey(pt => pt.TagId);
    }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public List<PostTag> PostTags { get; set; }
}

public class Tag
{
    public string TagId { get; set; }
    public string Title { get; set; }
    public List<PostTag> PostTags { get; set; }
}

public class PostTag
{
    public int PostId { get; set; }
    public Post Post { get; set; }
    public string TagId { get; set; }
    public Tag Tag { get; set; }
}

我必须添加一个构造函数才能让它运行。我还在Tag类中添加了一个Title字段,因此它不仅仅是一个键。一旦我在表中填充了一些数据,我就运行以下代码从数据库中检索:

var results = _context.Posts.Include(s => s.PostTags).ToList();

当我在调试器中检查结果时,即使存在获取它们的密钥,Tag对象也是null。请注意,将填充Post对象。它始终是未连接的两列键的第二列: enter image description here

这是EF7生成的SQL:

  

SELECT [s]。[PostId],[s]。[Content],[s]。[Title]   来自[帖子] AS [s]   ORDER BY [s]。[PostId]

     

SELECT [p]。[PostId],[p]。[TagId]   来自[PostTag] AS [p]   在哪里(       选择1       来自[帖子] AS [s]       在哪里[p]。[PostId] = [s]。[PostId])   ORDER BY [p]。[PostId]

它似乎根本没有取得Tag对象。我在这里缺少什么?

为了完整起见,我已经包含了样本数据: enter image description here

2 个答案:

答案 0 :(得分:1)

感谢@SOfanatic将我指向了正确的方向。我不确定为什么EF不会自动加载第二个引用类,但事实并非如此。以下代码将检索Tag对象(以及Post对象,即使我们没有显式加载它)。

 var results = _context.Posts.Include(s => s.PostTags).ThenInclude(t => t.Tag).ToList();

答案 1 :(得分:0)

您正在使用所谓的Payload class进行多对多操作。从技术上讲,EF PostTag类不需要创建多对多关系。

你将不得不做这样的事情:

var results = _context.Posts.Include(s => s.PostTags.Select(pt => pt.Tag).ToList();

现在你的linq正在加载相关实体,这些实体只是id,所以没有用。 如果您的PostTags课程没有任何其他字段/属性,那么您应该考虑在没有payload

的情况下创建多对多课程