c# - EF LINQ - Return entities that contain an entire collection -
i trying troubleshoot following linq query:
public jsonresult searchnodesbytags(string[] tags) { var nodes = _dbcontext.nodes. where(n => n.tags.all(t => tags.contains(t.displayname))) .select(n => new {n.nodenativeid, n.nodename, n.nodeclass.classname}) .tolist(); return json(nodes); } the query returning single node not associated tag. want do, return nodes have tags.
.where(n => n.tags.all(t => tags.contains(t.displayname)))
the way constructed, you're going end nodes every tag in node.tags has name in tags whitelist, includes nodes no tags.
you might want use answer here on subsets:
_dbcontext.nodes .where(n => !tags.except(n.tags.select(t => t.displayname)).any()) .select(... set1.except(set2)contains elements ofset1aren't inset2!set1.except(set2).any() == trueifset2includes every element ofset1
edit
it pointed out in comments using except generate problematic queries, thinking option superset database, , further filter objects within application:
_dbcontext.nodes // filter nodes of input tags .where(n => n.tags.any(t => tags.contains(t.displayname))) // select information required .select(n => new { n.nodenativeid, n.nodename, classname = n.nodeclass.classname, tagnames = n.tags.select(t => t.displayname) }) // materialize super set database .tolist() // filter nodes tags remain .where(n => !tags.except(n.tagnames).any()) // produce result in anonymous class .select(n => new { n.nodenativeid, n.nodename, n.classname }) .tolist(); edit 2
i saw 1 here might work you, requires tag.displayname unique, since fail if have multiple tags same displayname:
_dbcontext.nodes .where(n => n.tags.count(t => tags.contains(t.displayname)) == tags.count) .select(...
Comments
Post a Comment