简体   繁体   English

linq 其中包含列表中的所有项目

[英]linq where contains ALL items in list

I have a list of filters and I want to use it to query a table where the returned items contain ALL of the values not just 1.我有一个过滤器列表,我想用它来查询一个表,其中返回的项目包含所有值,而不仅仅是 1。

For example I have a label/tag system.例如,我有一个标签/标签系统。 I want to return records that have the tag 'sport' AND 'football' in them.我想返回其中包含“运动”和“足球”标签的记录。 However 'sport' and 'football' are stored in a list and could be any number of other tags that the user supplies.然而,'sport' 和 'football' 存储在一个列表中,并且可以是用户提供的任意数量的其他标签。

I'm using entity framework.我正在使用实体框架。 I have a Tags, Teams, TeamTags table.我有一个 Tags、Teams、TeamTags 表。 My current query is as such:我当前的查询是这样的:

string _tags = "sport,football";
List<string> tags = _tags.Split(',').ToList();

var teams = (from t in db.Tags where tags.Contains(t.TagName) select t.Teams).FirstOrDefault().Select(i => i.TeamNames).ToList()

But this will return all teams that have the 'sport' tag not those that are labeled as 'sports' AND 'football' only.但这将返回所有具有“运动”标签的球队,而不是那些仅被标记为“运动”和“足球”的球队。

If you imagine typing the 'sport' tag first you'd get a list of teams from all sports.如果您想象先输入“运动”标签,您会得到所有运动队的列表。 Then you add the 'football' tag that list would be filtered even more to just the football teams.然后,您添加“足球”标签,该标签将被更多地过滤到足球队。 So my code above basically does an OR in the where.所以我上面的代码基本上在 where 中做了一个或。 I want the ability to do an AND as well.我也希望能够执行 AND。

So example data in the database would be:因此数据库中的示例数据为:

Broncos has sport and football tags Mets has sport and baseball tags野马队有运动和足球标签 大都会队有运动和棒球标签

I want the team that has sport AND football tags, not sport OR football tags.我想要拥有运动和足球标签的球队,而不是运动或足球标签。

I would suggest giving this a try: 我建议尝试一下:

var teams = (from team in db.Teams 
             where tags.All(tag => team.Tags.Any(ttag => ttag.TagName == tag))
             select team).ToList();

From there, if you want a list of the names, you can do a projection on that (it's hard to entirely grok how your data structures are set up, but something like this): 从那里,如果你想要一个名单列表,你可以对它做一个投影(很难完全了解你的数据结构如何设置,但是这样的事情):

var teamNames = teams.Select(t => t.Name).ToList();
string _tags = "sport,football";
List<string> tags = _tags.Split(',').ToList();

var teams = (from t in db.Tags where tags.All(x=> x.Contains(t.TagName)) select t.Teams).FirstOrDefault().Select(i => i.TeamNames).ToList();

This should help get you the desired result 这应该有助于获得理想的结果

I know it's kinds lame, but to get EF core working, and return only elements where a collection suppose to contain all elements I had to do something like this:我知道这有点蹩脚,但要让 EF 核心正常工作,并仅返回集合假设包含所有元素的元素,我必须执行如下操作:

            // var query = context....;

            foreach (var tag in tags)
            {
                query = query.Where(p => p.TagList.Any(t => t == tag));
            }

            return query;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM