public static KeyExpressions GetAllExistingKeys(Workspace w, ResourceContainer resourceContainer, ResourceType resourceType) { IEnumerable <ContainmentAttribute> attributes = GetContainmentAttributes(w.ServiceContainer, ca => ca.ChildContainer == resourceContainer); // should we pick one path at random? just use the first? determine which is shortest? ContainmentAttribute att = attributes.FirstOrDefault(); if (att == null) { QueryNode query = Query.From( Exp.Variable(resourceContainer)) .Select(); if (resourceType != null) { query = query.OfType(resourceType); } return(w.GetAllExistingKeys(query, resourceContainer)); } // recursively get all the parent container's keys // since we don't know the exact parent type, don't use one // KeyExpressions parentKeys = GetAllExistingKeys(w, att.ParentContainer, null); // we're doing some extra work by re-determining the parent key's access path, // but it would be hard to keep it around // KeyExpressions childKeys = new KeyExpressions(); foreach (KeyExpression parentKey in parentKeys) { // we don't necessarily need a canonical path QueryNode q = BuildQuery(parentKey, false); q = q.Nav(att.ParentNavigationProperty.Property()).Select(); if (resourceType != null) { q = q.OfType(resourceType); } foreach (KeyExpression childKey in w.GetAllExistingKeys(q, resourceContainer)) { childKeys.Add(childKey); } } return(childKeys); }
public static QueryNode BuildQuery(KeyExpression keyExp, List <AccessPathSegment> path, bool setOnly) { QueryNode query = null; if (path.Count() == 0) { query = Query.From(Exp.Variable(keyExp.ResourceContainer)); } else { query = Query.From(Exp.Variable(path.First().Attribute.ParentContainer)); foreach (AccessPathSegment segment in path) { query = query.Where(segment.ParentKey); query = query.Nav(segment.Attribute.ParentNavigationProperty.Property()); } } if (!setOnly) { query = query.Where(keyExp); } return(query); }