在实体框架中加入3对多表

时间:2017-02-06 20:42:03

标签: c# entity-framework linq join many-to-many

我有2个表,每个表与表之间有一对多关系,表之间有2个其他表的ID

dbo.Posts          dbo.Posts_Categories          dbo.Categories
   -ID                -ID                           -ID
   -Title             -PostID                       -Name
                      -CategoryID

我期望的结果是:

Title = post1          Categories = web,mobile,desktop
Title = post2          Categories = app,game
...

我知道如何使用Stuff函数和For Xml Path在sql中查询,但我不知道如何在实体框架中执行此操作!

任何有关如何以这种方式开展工作的建议或书籍都可能有所帮助!

编辑:EF类已添加:

    public class Post : ReportingBase {
        public Post() { }

        [Required, MaxLength(500)]
        public string Title { get; set; }
        [Required, MaxLength(500)]
        public string Address { get; set; }
        [Required]
        public string Body { get; set; }
        [Required, MaxLength(500)]
        public string Tags { get; set; }
        [Required]
        public int Visit { get; set; }



        public virtual ICollection<Post_Category> Posts_Categories { get; set; }
        public virtual ICollection<Post_AttachedFile> Posts_AttachedFiles { get; set; }

        [ForeignKey("Image")]
        public virtual int? ImageID { get; set; }
        public virtual Image Image { get; set; }
    }

    public class Post_Category {
        public Post_Category() { }

        [Key, Column(Order = 0)]
        public int PostID { get; set; }

        [Key, Column(Order = 1)]
        public int CategoryID { get; set; }

        public virtual Post Post { get; set; }
        public virtual Category Category { get; set; }
    }

    public class Category : EntityBase {
        public Category() { }

        [Required, MaxLength(50)]
        public string Name { get; set; }

        [Required, MaxLength(150)]
        public string Address { get; set; }
        public int? ParentID { get; set; }



        public virtual ICollection<Post_Category> Posts_Categories { get; set; }
    }

提前谢谢

编辑:根据@IvanStoev的回答,我做了以下操作:

    List<P> p = context.Posts.Select(post => new {
        Title = post.Title,
        Categories = post.Posts_Categories.Select(pc => pc.Category.Name).ToList()
    }).ToList();

并创建了一个名为P:

的类
public class P {
    public string Title { get; set; }
    public List<string> Categories { get; set; }
}

但它无法正常工作,问题是如何返回结果。

3 个答案:

答案 0 :(得分:2)

在EF中,由于所谓的navigation properties的概念,它比在SQL中更容易。您需要知道的只是一个基本的LINQ查询语法,只需按照它们(导航)即可获得所需的数据。例如:

var result = db.Posts
    .Select(post => new
    {
        Title = post.Title,
        Categories = post.Posts_Categories
            .Select(pc => pc.Category.Name)
            .ToList()
    })
    .ToList();

结果是一个匿名类型列表,其中包含string Title属性和List<string> Categories属性,其中包含相关的类别名称。

答案 1 :(得分:1)

您可以使用Linqpad(软件)熟悉Linq查询,它通过连接到数据库为您构建lambda表达式,并提供输出以进行交叉验证。

下面是用于连接您提到的表的lambda表达式。

p - Post  
pc - post_categories
c - categories

代码:

Posts.Join(Post_Categories, p => p.ID, pc => pc.ID, ( p, pc) => new { p = p, pc = pc})
     .Join(Categories, pcc => pcc.pc.CategoryID, c => c.ID, ( pcc, c) => new { pcc = pcc, c = c})
     .Select(p.Title)
     .Select(c.Name)

答案 2 :(得分:0)

您应该使用 .Include()任何加入 EF Core。

我想出了一个简单的例子:一个人可以拥有多只狗

public class Person
{
    public Guid Id { get; set; }
    public ICollection<Dog> Dogs { get; set; } // One Person can have many Dogs
}

public class Dogs
{
    public Guid Id { get; set; }
    public Guid PersonId { get; set; }
}

在创建模型后生成迁移。在这个答案中不讨论如何做到这一点。

以下是如何使用 .Include() 连接两个不同的表:

public class PersonRepository : RepositoryBase
{
    public IEnumerable<Person> FetchPeopleWithManyDogs()
    {
        return DatabaseContext.Person
            .Include(x => x.Dogs)
            .Where(x => x.Dogs.Count() > 1).ToList();
    }
}