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 node
s every tag in node.tags
has name in tags
whitelist, includes node
s 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 ofset1
aren't inset2
!set1.except(set2).any() == true
ifset2
includes 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