Search code examples
c#entity-frameworklinqjoinmany-to-many

Join 3 One to Many Tables in Entity Framework


i have 2 tables that each one has a one-to-many relation to the table between and the table between has ids of 2 other tables

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

result i expect is :

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

i know how to query this in sql using Stuff function and For Xml Path but i have no idea how do i do this in entity framework!

any suggestion or book for how to do works in this way might help!

Edit: EF classes added:

    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; }
    }

thank you in advance

Edit : According to @IvanStoev answer i did following :

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

and created a class called P :

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

but it doesn't work correctly and the problem is how to return the result.


Solution

  • In EF it's even easier than in SQL thanks to the concept of so called navigation properties. All you need to know is a basic LINQ query syntax and just follow them (navigate) to get the data needed. For instance:

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

    The result is a list of anonymous type having string Title property and List<string> Categories property containing the related category names.