我正在尝试查找所有帖子包含所有选定的标签。
我当前的代码返回包含所有选定标签的帖子以及包含一些所选标签的帖子。
这是我的功能。感谢您的帮助。
示例数据库结构
表
[发布] - ID - 标题 - 身体
[PostTag] - ID - PostId - TagName
所以[Post]的帖子与PostId的一对多关系是外键。
public static IEnumerable<Post> getPostContainsAllTags(IEnumerable<string> _SelectedTags,
int numPosts)
{
using (MaplePrimesDataContext dc = new MaplePrimesDataContext(_connectionString))
{
var tagPosts = (from p in dc.Posts
join t in dc.PostTags on p.Id equals t.PostId
where p.Status == 1 && _SelectedTags.Contains(t.Name)
orderby p.DateAdded descending
select p).Take(numPosts).ToList();
return tagPosts;
}
}
答案 0 :(得分:2)
我还会将数据库结构更改为不复制PostTag
表
这很有效,很容易理解:
var tagPosts = dc.Posts.Where(post => post.Status == 1);
foreach (var selectedTag in _SelectedTags)
{
tagPosts = tagPosts.Where(post => post.PostTags.Any(tag => tag.Name == selectedTag));
}
return tagPosts.OrderByDescending(p => p.DateAdded).Take(numPosts).ToList();
这也有效,而且速度更快
var selectedTagIds = dc.Tags.Where(tag => _SelectedTags.Contains(tag.Name)).Select(x => x.TagId);
var tagPosts = dc.Posts
.Where(post => post.Status == 1)
.Where(post =>
!(from selectedTag in selectedTagIds
join tag in post.PostTags on selectedTag equals tag.TagId into postTags
from tag in postTags.DefaultIfEmpty()
where tag.TagId == null
select 1).Any());
return tagPosts.OrderByDescending(p => p.DateAdded).Take(numPosts).ToList();
这里的区别在于我们首先创建一个数据库集合selectedTagIds
,然后使用它来进行左连接(在LINQ中非常难看 - &gt; https://msdn.microsoft.com/en-us/library/bb397895.aspx)
它有效,因为如果帖子没有标记,那么该帖子标记和所选标记的左连接将有一行没有帖子标记。
答案 1 :(得分:0)
dc.Posts.Select
.Join(p=>p.Id, dc.PostTags, (p, pt)=>new{Post = P, PostTag = pt})
.Where(o=>SelectTags.Contains(o.PostTag))
.GroupBy(o=>o.Post, o=>o.PostTag)
.Select(g=>new{Post=>g.Key, Count=>g.Count()})
.Where(o=>o.Count == SelectTags.Count())
.Select(o=>o.Post)
.OrderByDescending(o=>o.DateAdded)
.Take(numPosts)
.Tolist()
注意 - 我刚刚在这里打字,可能不是最佳方式
我在这里做的是我选择
1.选择带标签的标签
2.过滤掉所有记录不在SelectedTags列表中
3.然后按产品分组,制作Enumerable
objects
个帖子为key
,(No of Tags)
为value
。
4.然后再次使用(Count Of Tags)
!= (Count of SelectedTags)
答案 2 :(得分:0)
如果您有另一个包含所有可用标记的Tag表,您可以考虑使用简单的Count:
var postsIds = (from p in posts
join t in postTags on p.Id equals t.PostId
group p by p.Id into grp
where grp.Count() == tags.Count()
select grp.Key).ToList();