我与这 3 个表有典型的多对多关系

[Post] (
  [PostId] int, (PK)
  [Content] nvarchar(max)
   ...
)

[Tag] (
  [TagId] int, (PK)
  [Name] nvarchar
  ...
)

[TagPost] (
  [TagId] int, (PK, FK)
  [PostId] int (PK, FK)
)

而且,TagId 和 PostId 是相应地在表上设置的 PK 和 FK。然后我在 c# 中有这些类和映射
public class Post {
    public Post()
    {
        this.Tags = new HashSet<Tag>();
    }

    [Key]
    public int PostId { get; set; }
    ...

    public virtual ICollection<Tag> Tags { get; private set; }
}

public class Tag {
    public Tag()
    {
        this.Posts = new HashSet<Post>();
    }

    [Key]
    public int TagId { get; set; }
    ...

    public virtual ICollection<Post> Posts { get; private set; }
}

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

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Post>().ToTable("Post");
        modelBuilder.Entity<Tag>().ToTable("Tag");

        modelBuilder.Entity<Post>()
            .HasMany(x => x.Tags)
            .WithMany(x => x.Posts)
        .Map(x =>
        {
            x.ToTable("TagPost");
            x.MapLeftKey("PostId");
            x.MapRightKey("TagId");
        });
    }

然后我有这个代码来查询它们
var list = (from p in ctx.Posts.Include(p => p.Tags)
            from t in p.Tags
            where ... // some of my filter conditions
            select p).ToList();

这个连接确实返回了我正在寻找的帖子,但是即使我在那里有 Include,返回的帖子也没有填写它们的关联标签。有人可以帮助指出我遗漏了什么,以便我可以让标签也随帖子一起返回吗?

非常感谢。

最佳答案

from 是手动 Join ,它会导致 Include 被忽略,如提到的 herehereInclude 也被其他 LINQ 方法 like grouping and projections 忽略。

关系修正通常不适用于多对多关系,仅适用于在一端至少有一个单一引用的关系 - 一对多或一对一。如果您将 Posts 和相关的 Tags 投影到另一种类型(匿名或命名),数据将被正确加载,但由于关系是多对多的,EF 不会自动在内存中创建关系,因此 post.Tags 集合将保持为空.

要使 Include 工作,您必须从查询中删除第二个 from 并将 where 子句直接应用于 Post 实体参数,例如:

var list = (from p in ctx.Posts.Include(p => p.Tags)
            where p.Tags.Any(t => t.TagId == 1)
            select p).ToList();
Tag 属性的过滤器在传递给 .Any 的表达式中指定,Tag 是一个以 t ( ojit_code ) 作为参数的表达式。

关于linq - Entity Framework 多对多工作,但包括不,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15556134/

10-12 22:20