Is there another way to make this LINQ query work?
Well I have this: Board:
public class Board
{
public int BoardID { get; set; }
public string BoardName { get; set; }
public string BoardDescription { get; set; }
public int PostCount { get; set; }
public int TopicCount { get; set; }
public bool IsVisibile { get; set; }
public Forum BelongToForum { get; set; }
public List<Board> Boards { get; set; }
public List<Topic> Topics { get; set; }
}
And Forum:
public class Forum
{
public int ForumID { get; set; }
public string ForumName { get; set; }
public string ForumDescription { get; set; }
public List<Board> Boards { get; set; }
}
And method that get Forums with boards:
public List<Forum> GetForums()
{
List<Forum> forums = new List<Forum>();
_ctx = new ForumContext();
forums = (from p in _ctx.Forums
select p).ToList();
List<Forum> returnForm = new List<Forum>();
foreach(Forum forum in forums)
{
List<Board> board = (from x in _ctx.Boards
where x.BelongToForum.ForumID == forum.ForumID
select x).ToList();
forum.Boards = board;
returnForm.Add(forum);
}
return returnForm;
}
It's working as expected. But as you see I'm using three lists, and foreach loop. It doesn't look really good for me. So I have an question, is 开发者_高级运维there another way to make it work ?
I think I should made another model class that will gather nessesary data from join or something like this. But what I want to ask are there other ways to do it ?
If you look at your Forum
entity it already has a Boards
property. You should be able to materialize those in one query using Include()
.
forums = (from p in _ctx.Forums.Include("Boards")
select p).ToList();
Or using the strongly typed Include()
:
forums = (from p in _ctx.Forums.Include( x=> x.Boards)
select p).ToList();
Can you clarify whether this is code first or DB first? From your example it looks like DB first with POCO models (with code first the Boards
property should have been materialized already since it is not marked as virtual).
This should work:
var returnForm =
(
from forum in _ctx.Forums
join b in _ctx.Boards on forum.ForumID equals b.BelongsToForum.ForumID into boards
select new { forum, boards }
)
.Select( x =>
{
x.forum.Boards = x.boards.ToList();
return x.forum;
} )
.ToList();
The tricky part is with assigning the list of boards to the forum.Boards
property. This doesn't quite fit the LINQ philosophy: LINQ is about creating next set of data from previous set of data via some kind of transformation, not about modifying the data in place.
For this reason, this assignment part came out a bit ugly.
However, if you're using LINQ-to-entities, it probably has some more elegant ways to accomplish what you're trying to accomplish. I'm not a big pro in that technology, though.
精彩评论