Asp.net mvc 至少包含实体框架中的所有

Asp.net mvc 至少包含实体框架中的所有,asp.net-mvc,linq,entity-framework,Asp.net Mvc,Linq,Entity Framework,我的数据库中有以下两个实体 public class Article { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } // Some code removed for brevity public virtual ICollection<Tag> Tags { get; set; } } public class Tag {

我的数据库中有以下两个实体

public class Article
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    // Some code removed for brevity

    public virtual ICollection<Tag> Tags { get; set; }
}


public class Tag
{

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    // Some code removed for brevity

    public virtual ICollection<Article> Articles { get; set; }

}
公共类文章
{
[数据库生成(DatabaseGeneratedOption.Identity)]
公共int Id{get;set;}
//为了简洁起见,删除了一些代码
公共虚拟ICollection标记{get;set;}
}
公共类标签
{
[数据库生成(DatabaseGeneratedOption.Identity)]
公共int Id{get;set;}
//为了简洁起见,删除了一些代码
公共虚拟ICollection项目{get;set;}
}
我需要根据传递到我的操作中的标记ID筛选这些文章

public ActionResult FindAll(List<int> tags)
{

    //
    // I need to return all articles which have ALL the tags passed into this method
    //

    var query = ApplicationDbContext.Articles...


}
public ActionResult FindAll(列表标记)
{
//
//我需要返回将所有标记传递到此方法的所有文章
//
var query=ApplicationDbContext.Articles。。。
}
例如,如果我将1、2、3传递到操作中,则只返回具有这3个或更多标记的文章

我怎样才能做到这一点

感谢您的大力响应

您的所有回答都产生了正确的结果,因此我使用sql进行了一些快速、基本的分析,这是基于您的查询的结果

使用或类似

Except()
将为您提供第一个列表中在第二个列表中不存在的项目

Except运算符生成两个序列之间的集合差。 它将只返回第一个序列中未出现的元素 在第二个


通过IQueryable迭代构建结果

public ActionResult FindAll(List<int> tags)
{
    var queryable = ApplicationDbContext.Articles.AsQueryable();

    foreach(var t in tags)
    {
        queryable = queryable.Where(w => w.Tags.Any(a => a.Id == t));
    }

    queryable.AsEnumerable();   // stuff this into a viewmodel and return actionresult?
}
public ActionResult FindAll(列表标记)
{
var queryable=ApplicationDbContext.Articles.AsQueryable();
foreach(标签中的var t)
{
queryable=queryable.Where(w=>w.Tags.Any(a=>a.Id==t));
}
queryable.AsEnumerable();//将其填充到viewmodel中并返回actionresult?
}
使用以下方法:

ApplicationDbContext.Articles.Where(a => tags.All(t => a.Tags.Contains(t)));
这应该做到:

ApplicationDbContext.Articles.Where(a => tags.All(t => a.Tags.Any(at => at.Id == t)));
试试这个:

  var query =from a in ApplicationDbContext.Articles
             where a.Tags.Count(t => tags.Contains(t.Id)) == tags.Count
             select a;
这个怎么样

var articles = ApplicationDbContext.Articles.Where (a => a.Tags.Select (t => t.Id).Intersect(tags).Count()>=tags.Count);

这只适用于只有匹配标签且没有更多标签的文章。。。。对吗?我不认为这是OP想要的,因为他说他至少想要指定的标签,不仅如此。@adam0101,我已经更正了我的答案,它应该可以工作了,因为看起来你的现在可以工作了。。。很好的解决方案。我试图想出一个1号班轮,但失败了+1Article标记是具有Id属性的对象,而不是整数。我想你需要再调整一下,这是不对的。他希望匹配所有指定的标记,而不是文章上的所有标记。这看起来很正确,只是文章标记是一个具有Id属性的对象,而不是一个整数。对于那些
除外
所有
答案,您可能需要检查以确保性能可接受您期望的负载,如果
tags.Count
很大,则生成的SQL仍然有效。有关更多详细信息,请参阅下面的注释。可能值得查询文章的超集(带有任何标签?)并进行进一步筛选。如果所有答案都不起作用或您仍面临问题,请告诉我,以便我能提供帮助。我很好奇:您在这些测试中使用了多少标签,
articles
表有多大,结果集有多大?我认为你的第一次修订是正确的。现在,这与标签的确切数量相匹配,而这不是OP想要的。@adam0101,第一个查询返回的文章中至少有一个标签与标签列表中的标签匹配。现在,对于第二个查询,我不仅仅检查标记的数量是否相同,还要检查子查询中的条件,如果包含的标记数量与
标记列表中的元素数量匹配,那么我选择文章
其中a.tags.Count(t=>tags.Contains(t.Id))==tags.Count
?我甚至不知道存在一个
所有的
。美好的谢谢你的回答!我在另一篇评论中看到,你试图把这当作一句台词。这可以使用聚合方法实现。Aggregate(ApplicationDbContext.CaseStudies.AsQueryable(),(current,t)=>current.Where(w=>w.tags.Any(a=>a.Id==t));
var articles = ApplicationDbContext.Articles.Where (a => a.Tags.Select (t => t.Id).Intersect(tags).Count()>=tags.Count);