1

I have a list like this ( already open with the visual studio debugger ) :

enter image description here

As you can see the list is made ​​up of other objects of the same type list , my need is to run through all the children , regardless by the Index and verify that the FID of that object is the same as the one passed by the UI . Once you found matching server that returns the same object .

i can try this for test, but considering I only top-level items , those with index 0 , does not flow in all:

AttachmentFolders childWithId17 = ApplicationContext.Instance.companyList[0].AttachmentFolders.SelectMany(parent => parent.AttachmentFolder)
                             .FirstOrDefault(child => child.FID == "835A09A2-9D60-46CC-A2BE-D4CBC4C81860");

another picture to better understand

enter image description here

in fact, I get a list with many elements and should scroll it all , even in responsive manner to be able to return the object that corresponds to that AttachmentFolders FID .

class structure:

public class AttachmentFolders
    {
        public int id { get; set; }
        public String FID { get; set; }
        public String Name { get; set; }
        public String CPID { get; set; }
        public String ParentFID { get; set; }

            public List<Attachment> Attachments { get; set; }
            public List<AttachmentFolders> AttachmentFolder { get; set; }
        }

public class Attachment
    {
        public int id { get; set; }
        public String ATID { get; set; }
        public String Name { get; set; }
        public String CreatorID { get; set; }
        public String FID { get; set; }
        public String Extension { get; set; }
        public String Description { get; set; }
        public int Status { get; set; }
        public String CPID { get; set; }
        public int FileSize { get; set; }
        public DateTime CreationDate { get; set; }
        public DateTime ModifiedDate { get; set; }
        public int AttachmentType { get; set; }
        public int ValidityType { get; set; }
        public List<Revisions> Revisions { get; set; }
        public String AWID { get; set; }
        public String WAID { get; set; }
        public String WatermarkPositions { get; set; }
        public Boolean Serveroffline { get; set; }
        public Boolean IsFavourite { get; set; }
        public DateTime LastOpenDate { get; set; }
        public int Priority { get; set; }
        public String CreatorFirstName { get; set; }
        public String CreatorLastName { get; set; }
        public String ModifiedByFirstName { get; set; }
        public String ModifiedByLastName { get; set; }
        public String[] Capabilities { get; set; }
    }

Thank you all.

Mr. Developer
  • 3,295
  • 7
  • 43
  • 110

2 Answers2

1

You can write something like the SelectDeep extension as in this Marc's answer: Expressing recursion in LINQ

and then use it in your code instead of SelectMany:

AttachmentFolders child = companyList[0].AttachmentFolders
    .SelectDeep(parent => parent.AttachmentFolder)
    .FirstOrDefault(child => child.FID == "835A09A2-9D60-46CC-A2BE-D4CBC4C81860");

The SelectDeep method looks as follows:

public static class EnumerableExtensions
{
    public static IEnumerable<T> SelectDeep<T>(
        this IEnumerable<T> source, Func<T, IEnumerable<T>> selector) {
        foreach (T item in source) {
            yield return item;
            foreach (T subItem in SelectDeep(selector(item), selector)) {
                yield return subItem;
            }
        }
    }
}
Community
  • 1
  • 1
romanoza
  • 4,775
  • 3
  • 27
  • 44
  • how to add SelectDeep ? i don't have definition in visual studio – Mr. Developer Feb 26 '16 at 12:50
  • forgive me , but I can not understand the code , that is, how to apply , can you clarify ? – Mr. Developer Feb 26 '16 at 13:34
  • @Mr.Developer Definition of function `SelectDeep` is in my answer. You can use it to return all of the items from the nested structure (tree). Just use this function intead of `SelectMany`. – romanoza Feb 26 '16 at 15:35
  • i have this error on SelectDeep: Extension methods must be defined in a top level static class; EnumerableExtensions is a nested class, how to solve ? if possible, thanks – Mr. Developer Feb 26 '16 at 15:38
  • @Mr.Developer You can't place the `EnumerableExtensions` class within another class. It must be placed at top level, outside of any class. – romanoza Feb 26 '16 at 15:43
  • What ... a careless mistake by newbies , I put it out of the classroom and now it works . Thanks for your patience. Everything works – Mr. Developer Feb 26 '16 at 16:03
-1

This is a typical recursion case. You could try searching a flattened tree structure, as done in this or this answer.

If you experience slow performance of this solution, I would think about creating a helper Dictionary<string, AttachmentFolders> object, which would hold all (sub)folder references for quick access, e.g.

IEnumerable<AttachmentFolders> Flatten(AttachmentFolders f)
{
    var fs = new[] { f };
    return f.Children == null? fs : fs.Concat(f.Children.SelectMany(Flatten));
}

Dictionary<string, AttachmentFolders> GenerateCache(AttachmentFolders firstFolder)
{
    return Flatten(firstFolder).ToDictionary(f => f.FID, f => f);
}

Then, one-time at start:

Dictionary<string, AttachmentFolders> Cache = GenerateCache(firstFolder);

And each time a request is made:

if(Cache.ContainsKey(fid)) return Cache[fid];
else throw new Exception("Handle not found FID here");
Community
  • 1
  • 1
Robert Synoradzki
  • 1,766
  • 14
  • 20