Reputation: 815
I have a social networking website and I'm getting some difficulties to filter who can see the updates users post.
As in Facebook, I see all posts from my friends, even if I didn't post anything. I have these tables:
DiaryPosts table:
--------------------------------------
| ID | UserID | Content | UpdateTime |
--------------------------------------
Friends table:
--------------------------
| ID | UserID | FriendID |
--------------------------
Followers table:
----------------------------
| ID | UserID | FollowerID |
----------------------------
And I have this query that now it can't filter anything:
var diaryPosts = (from d in db.DiaryPosts
orderby d.ID descending
select new DiaryPostsSet
{
PostID = d.ID,
Author = db.User.Where(m => m.ID == d.UserID).FirstOrDefault().Nickname,
Thumbnail = db.User.Where(m => m.ID == d.UserID).FirstOrDefault().Thumbnail,
AuthorComment = d.Content,
UserID = d.UserID,
Time = d.UpdateTime }).Take(6).ToList();
I tried to write a where clause but it didn't work. Do you have any suggestions on how to write this query?
Upvotes: 1
Views: 507
Reputation: 815
The answer is:
//queries for diary Posts
var myDiaryPosts = (from d in db.DiaryPosts
join e in db.EstadosDeAlma
on d.EstadosDeAlmaID equals e.ID
join u in db.User
on d.UserID equals u.ID
where d.UserID == userset.ID
select new DiaryPostsSet {
PostID = d.ID,
EstadoDeAlmaID = e.ID,
EstadoDeAlma = e.Title,
Author = u.Nickname,
Thumbnail = u.Thumbnail,
UserID = u.ID,
IsDuplicated = d.IsDuplicated,
FriendID = d.FriendID,
FriendName = u.Nickname,
Time = d.UpdateTime,
MessagesCount = d.FriendMessages.Count(m => m.DiaryPostsID == d.ID)
});
var friendsPosts = (from d in db.DiaryPosts
join e in db.EstadosDeAlma
on d.EstadosDeAlmaID equals e.ID
join fr in db.Friends
on d.UserID equals fr.FriendID
where fr.UserID == userset.ID
join u in db.User
on fr.FriendID equals u.ID
select new DiaryPostsSet
{
PostID = d.ID,
EstadoDeAlmaID = e.ID,
EstadoDeAlma = e.Title,
Author = u.Nickname,
Thumbnail = u.Thumbnail,
UserID = u.ID,
IsDuplicated = d.IsDuplicated,
FriendID = d.FriendID,
FriendName = u.Nickname,
Time = d.UpdateTime,
MessagesCount = d.FriendMessages.Count(m => m.DiaryPostsID == d.ID)
});
var followingsPosts = (from d in db.DiaryPosts
join e in db.EstadosDeAlma
on d.EstadosDeAlmaID equals e.ID
join fl in db.Followers
on d.UserID equals fl.UserID
where fl.FollowerID == userset.ID
join u in db.User
on fl.UserID equals u.ID
select new DiaryPostsSet
{
PostID = d.ID,
EstadoDeAlmaID = e.ID,
EstadoDeAlma = e.Title,
Author = u.Nickname,
Thumbnail = u.Thumbnail,
UserID = u.ID,
IsDuplicated = d.IsDuplicated,
FriendID = d.FriendID,
FriendName = u.Nickname,
Time = d.UpdateTime,
MessagesCount = d.FriendMessages.Count(m => m.DiaryPostsID == d.ID)
});
var diaryPosts = myDiaryPosts.Union(friendsPosts).Union(followingsPosts).OrderByDescending(d => d.Time).Take(6).ToList();
Upvotes: 0
Reputation: 13399
var diaryPosts = (from d in db.DiaryPosts
let friendsId = d.Friends.Select(f=>f.FriendID)
where d.UserID == currentUserId || friendsId.Any(d.UserID)
orderby d.ID descending
select new DiaryPostsSet
{
PostID = d.ID,
Author = d.Author.Nickname,
Thumbnail = d.Author.Thumbnail,
AuthorComment = d.Content,
UserID = d.UserID,
Time = d.UpdateTime
}).Take(6).ToList();
I think you need something like this, plz check syntax and you can come up with a join in stead of let if you like.
Upvotes: 1
Reputation: 2389
You should have relationships setup in your database and in your data tier (in your entity diagram). If so, you should rely on those relationships by using navigation properties, not by using recursive database calls. Consider this: for each of the items in your DiaryPosts table, you will make 2 calls to the database. So, 6 posts = 13 total database calls (1 to get the posts, then 6x2 to get the users).
Your query should look something like this:
var diaryPosts = (from d in db.DiaryPosts
orderby d.ID descending
select new DiaryPostsSet
{
PostID = d.ID,
Author = d.Author.Nickname,
Thumbnail = d.Author.Thumbnail,
AuthorComment = d.Content,
UserID = d.UserID,
Time = d.UpdateTime }).Take(6).ToList();
Upvotes: 0
Reputation: 4951
What did you try that failed? You can try moving your where clause outside of your dynamic select query:
var diaryPosts = (from d in db.DiaryPosts
where d.UserID==2 && d.SomethingElse=="someValue"
orderby d.ID descending
select new DiaryPostsSet
{
....
This will ensure that you are filtering the results before you get into your dynamic selection.
Upvotes: 0