LINQ:选择“使用多个标记发布”

  • 本文关键字:选择 LINQ c# linq
  • 更新时间 :
  • 英文 :


我正在尝试查找包含所有选定标签的所有帖子。

我当前的代码返回包含所有选定标签的帖子和包含一些选定标签的帖子。

这是我的函数。我感谢您的帮助。

示例数据库结构

[帖子] - 编号 -标题 -身体

[后标签] - 编号 - 后置 - 标签名称

所以[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)valueobjects进行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();

相关内容

  • 没有找到相关文章

最新更新