c# - LINQ 多对多交集

标签 c# linq entity-framework linq-to-sql

我正在尝试查询 Posts基于 Tags 的列表:

public class Post
{
  public int? Id {get;set;}
  public string Name {get;set;}
  public virtual ICollection<Tag> Tags {get;set;}
}
public class Tag
{
  public int? Id {get;set;}
  public string Name {get;set;}
  public vritual ICollection<Post> Posts {get;set;}
}

现在我想根据标签列表返回帖子: IList<Tag> searchTags = ParseTagsFromSearchString("tag1,tag2,tag3"); // this function checks the tags in the database, so all the primary keys are available in the list

当一篇文章包含一个或多个标签时,这些标签也存在于 searchTags 中它应该包含在结果中。我尝试了以下方法:

var q = from s in Context.Registrations
                    where s.Tags.Intersect(tagList)
                    select s;

错误:Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<Models.Tag>' to 'bool'

var q = from s in Context.Registrations
                    where s.Tags.Any(t => tagList.Any(t2 => t.Id.Value == t2.Id.Value))
                    select s;

运行时错误:NotSupportedException: Unable to create a constant value of type 'Models.Tag'. Only primitive types ('such as Int32, String, and Guid') are supported in this context. 有什么想法吗?

-- 1 月 4 日更新: 答案指向正确的解决方案,但在我的代码中我仍然有 NotSupportedException。可空整数是否可能导致此问题,因为它不是原始类型?

最佳答案

你就快完成了,只需将 Intersect(taglist) 更改为 Intersect(taglist).Any()

这是一个工作示例(按照您对 PostTag 的定义):

Tag tag1 = new Tag() { Id = 1, Name = "tag1" };
Tag tag2 = new Tag() { Id = 2, Name = "tag2" };
Tag tag3 = new Tag() { Id = 3, Name = "tag3" };

List<Post> posts = new List<Post>() {
    new Post() { Id = 1, Name = "post1", Tags = new Tag[] {tag1} },
    new Post() { Id = 2, Name = "post2", Tags = new Tag[] {tag2} },
    new Post() { Id = 3, Name = "post3", Tags = new Tag[] {tag3} },
    new Post() { Id = 4, Name = "post13", Tags = new Tag[] {tag1, tag3} },
};

List<Tag> searchTags = new List<Tag>() { tag1, tag2 };

IEnumerable<Post> matching = posts.Where(p => p.Tags.Intersect(searchTags).Any());
//matching now contains post1, post2 and post13

现在,在实际代码中,您可能不会对搜索列表和帖子中的标签使用相同的实例,因此您必须为标签覆盖 Equals 和 GetHashCode,或者在对 Intersect 的调用中提供 IEqualityComparer

关于c# - LINQ 多对多交集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8713879/

相关文章:

c# - 无限重复列表(用无限重复序列压缩有限列表)

c# - Linq 语句中的正则表达式?

c# - 为什么此 Linq 查询对 Count() 返回 0?

C# 发送群发邮件

c# - 在 WPF 列表框中禁用键盘导航

c# - c# 中的动态对象,其中键具有 $ 符号

entity-framework - 将数据库优先迁移到代码优先 - 从发布切换到迁移

c# - 如何制作网页渐变 ASP.NET 和 CSS?

c# - 将多个 DbContext 与通用存储库和工作单元一起使用

c# - 无法将类型 'x' 转换为类型 'y'。 LINQ to Entities 仅支持转换 EDM 原语或枚举类型