Multiple GroupBy LINQ, coupled with SharePoint, damn works good

My previous entry was about Clone TreeNode in a TreeView, to bypass the lack of a Clone method. As I mentioned I did prepare the data initially from SharePoint Lists (actually lookup lists).
1. Having Lists with Folders, and Sub-Folders, etc. each one of them a Content Type (just as a side node, I always work with Content type, in mostly whatever I do) and have an SPQuery looping through like so:
 

private void TraverseList(SPList list)

{

//Console.WriteLine(“Traversing list: “ + list.Title);
//Console.WriteLine(“Base Type: “ + list.BaseType.ToString());

TraverseListFolder(list.RootFolder);

}

private void TraverseListFolder(SPFolder folder)

{

// Get the collection of items from this folder

SPQuery qry = new SPQuery();
qry.Folder = folder;
SPWeb web = null
;

try
{

web = folder.ParentWeb;

SPListItemCollection ic = web.Lists[folder.ParentListId].GetItems(qry);

foreach (SPListItem subitem in ic)

{

//Console.WriteLine(“List item: “ + subitem.Name);
/Console.WriteLine(“List item type: “ + subitem.ContentType.Name);
if (subitem.Folder !=
null
)
TraverseListFolder(subitem.Folder);

}

}

catch (Exception e)

{

Console.WriteLine(e.Message);
}
finally
{
// Cleanup that nasty web reference.
if (web !=
null
)
web.Dispose();

}

}

 
2. Or…use LINQ (is that simple…or maybe not…but hell it did work like a charm for me). I know that guys concerned about performance issues will jump over…but what’a’heck….give some, get some. Another reason, actually that got me on this approach also because I was not the Owner of the lists, therefore I had to comply with what’s already there, and still do my part.
 
So by using some LINQ Query multiple GroupBy clauses. As I was researching for help in this direction, i did stumbled upon some really nice articles on the web about how to achieve the efect of multiple GroupBy.
One was using a loop, to perform a GroupBy and have the clause read from some string. This was not by far what I was needed as mine was required to be recursive…so we could get, let’s say something like, in a repeated fashion:
 
-Teritory
–Region
—Country
 
So….I found…again Extension Methods come to the rescue on Mitsu’s blog (all credits for this go to him: http://blogs.msdn.com/mitsu/archive/2008/02/07/linq-groupbymany-dynamically.aspx) and with little adaptions, I could reuse it. See below (few notes thought :DistributionCountry acts just like a property bag, plain and simple class, having some properties reading from columns values). Also note that the pound sign (#) must be removed from the value as lookup columns always return something like ID#VALUE.
 

private void LoadTreeFromCountriesList(string listUrl, TreeView tree)

{

using (SPWeb web = SPContext.Current.Site.OpenWeb("My Web Url")
{

SPList currList = web.Lists["My list"];
var countryListItems = currList.Items.Cast<SPListItem>();

List<DistributionCountry> countries = new List<DistributionCountry>();

foreach (SPListItem country in countryListItems)
{

countries.Add( new DistributionCountry()
{
Id = country[
"ID"].ToString(),Title = country["Title"].ToString(),Region = country["Default Region"].ToString(),Teritory = country["Default Teritory"
].ToString()
});

}

tree.Nodes.Clear();

foreach (Linq.GroupResult gr in countries.GroupByMany(c => c.Teritory, c => c.Region))
{

tree.Nodes.Add(GetTreeNodeFromGroup(gr));

}

}
}

private TreeNode GetTreeNodeFromGroup(Linq.GroupResult group)

{

TreeNode tn =

new TreeNode(getTitleOfLookupField(group.Key.ToString()));

if (group.SubGroups != null)

{

foreach (GroupResult gr in group.SubGroups)

{

tn.ChildNodes.Add(GetTreeNodeFromGroup(gr));

}

}

else

{

foreach (DistributionCountry country

in group.Items)
{

tn.ChildNodes.Add(

new TreeNode(country.Title, country.Id));

}

}

return tn;

}

private string getTitleOfLookupField(string titleOfLookupField)

{

return titleOfLookupField.Substring(titleOfLookupField.IndexOf("#") + 1);

}

 
 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s