我有一个记录列表,每个主记录中都有一个0到许多标志的列表。我试图提出一个Linq查询,以仅带回与标志列表中所有标志匹配的记录。
var flags = new List<string>() {"flag1","flag5"};
//The flags list could also be empty in which case it should match records with no flags set.
var tbs = db.MyContents
.Select(a => new {a.Id, FlagList=a.Flags.Select(f=>f.Name).ToList()})
.Where(f=>f.FlagList.Intersect(flags).Any());
上面的代码带回所有具有"flag1 ||flag5"
或"flag1 && flag5"
的记录。但是我想做的是只带回既有"flag1 && flag5"
有什么建议或想法吗?
答案 0 :(得分:2)
您可以尝试将Except
与NOT Any
结合使用,以确保flags
集合中的每个值都匹配。
var tbs = db.MyContents
.Select(a => new { a.Id, FlagList = a.Flags.Select(f => f.Name) })
.Where(f => !flags.Except(f.FlagList).Any());
编辑
我看到您在编辑问题,只需要在linq where
中添加一些逻辑
var tbs = c.Select(a => new { a.Id, FlagList = a.Flags.Select(f => f.Name) })
.Where(f => !flags.Except(f.FlagList).Any() && flags.Count() > 0 ||
flags.Count() == 0 && f.FlagList.Count() == 0);
答案 1 :(得分:1)
也许您可以将Where()
是:
.Where(f=>f.FlagList.Intersect(flags).Count() == flags.Count());
答案 2 :(得分:0)
因此,您有一个Records
序列,其中每个Record
都有一个Flags
序列。您还可以使用其他标志序列。
示例:
var oftherFlags = A B C
var records = record A with flags A B
record B with flags A B C
record C with flags B C
record D with flags A B C D
record E with flags A A A A A B C
“我想提出一个Linq查询以带回与所有标志匹配的所有记录”
显然,记录B可以。记录A和C缺少一些记录;您要录制D吗?它具有所有标志,甚至还有更多标志。那是问题吗?那记录E呢?您忘记指定任何有关重复项的信息
让我们假设所有Flag
序列都可能有重复,并且您不必担心重复。
因此以下内容将给出相同的结果
var otherFlags = A B C
var otherFlags = A B C C C C C
HashSet来营救!
IEnumerable<string> otherFlags = ...
var result = myRecords
// put the flags in a HashSet, this removes duplicates
.Select(record => new
{
Record = record,
FlagSet = new HashSet<string>(record.Flags),
})
// keep only those elements where the FlagSet is a superset of otherFlags
.Where(element => element.FlagSet.IsSuperSetOf(otherFlags)
.Select(element => element.Record);
如果应该考虑重复项,那么如果otherFlags
有两个A,而您只希望Records
有两个A,则可以使用Enumerable.Except
var result = myRecords
.Where(record => record.Flags // from every record take the flags
.Except(otherFlags) // remove all otherFlags
.Any()); // keep the record if there are still flags left