我正在尝试查找包含所有选定标签的所有帖子。
我当前的代码返回包含所有选定标签的帖子和包含一些选定标签的帖子。
这是我的函数。我感谢您的帮助。
示例数据库结构
表
[帖子] - 编号 -标题 -身体
[后标签] - 编号 - 后置 - 标签名称
所以[Post]到[PostTag]与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;
}
}
我还会更改数据库结构以不重复表中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 -> https://msdn.microsoft.com/en-us/library/bb397895.aspx 中非常丑陋)
它之所以有效,是因为如果帖子没有标签,则该帖子标签和所选标签的左侧连接将有一行没有帖子标签。
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. 过滤掉所有不在"选定标签"列表中的
记录3.然后按产品分组,以Post为key
,(No of Tags)
为value
,objects
进行Enumerable
。
4.然后再次过滤掉所有记录,(Count Of Tags)
!= (Count of SelectedTags)
如果您有另一个包含所有可用标签的标签表,则可以考虑使用简单的 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();