Select n Items from the Child List? - c#

how can I get N elements of the child list? Let's say I'd like to get 2 children for each parent.
public class Program
{
static void Main(string[] args)
{
var data = new List<Parent>()
{
new Parent()
{
Id = 1,
Name = "ParentName1",
Children = new List<Child>()
{
new Child() { Id = 1, Name = "ChildName1"},
new Child() { Id = 2, Name = "ChildName2"},
new Child() { Id = 3, Name = "ChildName3"},
new Child() { Id = 4, Name = "ChildName4"},
new Child() { Id = 5, Name = "ChildName5"},
}
},
new Parent()
{
Id = 2,
Name = "ParentName2",
Children = new List<Child>()
{
new Child() { Id = 6, Name = "ChildName6"},
new Child() { Id = 7, Name = "ChildName7"},
new Child() { Id = 8, Name = "ChildName8"},
new Child() { Id = 9, Name = "ChildName9"},
new Child() { Id = 10, Name = "ChildName10"},
}
}
};
// Get only 2 child elements for parent
var filteredData = data.Where(x => x.Children.Count >= 2)
.ToList();
foreach (var filteredParent in filteredData)
{
Console.WriteLine($"Parent {filteredParent.Id} with {filteredParent.Children.Count} children.");
}
Console.ReadKey();
}
}
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public string Name { get; set; }
public Parent Parent { get; set; }
}

One way to do it is to use a multi statement lambda expression for the result selector and List<T>'s RemoveRange method:
var query = data.Select
(
p =>
{
p.Children.RemoveRange(2, p.Children.Count - 2);
return p;
}
);
As Flater commented, It might be better to return a shallow copy of the parent, with only the first two children. That way your query does not change the source data:
var query = data.Select
(
p => new Parent()
{
Id = p.Id,
Name = p.Name,
Children = p.Children.Take(2).ToList()
}
);

Related

Filter List inside List Linq

I have list say list of customers and inside each list there is another list of orders
Class Customer
{
int ID,
string Name
List<Order> orders
}
Class Order{
int ID,
string Name
}
Also have a integer list of filteredorderIds = {1,2,3,4}
I want to filter the list of customers who has got orderIds from filteredorderIds list.
So far I am stuck at query like
var filteredCustomers = Customers.Where(x => x.Orders.Any(filteredorderIds.contains(y => y.Id)));
please give credit to #Johnathan Barclay, since he posted faster than i typed example
void Main()
{
var customers = new List<Customer>(){
new Customer(){
ID =1,
Name = "Cust1",
orders = new List<Order>(){
new Order(){ID = 4, Name = "o11"},
new Order(){ID = 5, Name = "o12"},
new Order(){ID = 6, Name = "o13"}
}
},
new Customer(){
ID = 2,
Name = "Cust2",
orders = new List<Order>(){
new Order(){ID = 3, Name = "o21"},
new Order(){ID = 7, Name = "o22"},
new Order(){ID = 8, Name = "o23"}
}
}
};
customers.Where(w =>
w.orders.Any(w => filteredorderIds.Contains(w.ID))
).Dump();
}
List<int> filteredorderIds = new List<int>() { 1, 2, 3, 4 };
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public List<Order> orders { get; set; }
}
public class Order
{
public int ID { get; set; }
public string Name { get; set; }
}

Convert categories into human readable breadcrumbs C#

I need a function that converts categories into flats (see code bellow).
I get categories from the database and then I want to convert them into a breadcrumbs format so I can later display them in a combobox.
using System.Collections.Generic;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
var categories = new List<ProductCategory>
{
new ProductCategory { ProductCategoryId = 1, ParentId = null, Name = "Drinks" },
new ProductCategory { ProductCategoryId = 2, ParentId = null, Name = "Food" },
new ProductCategory { ProductCategoryId = 3, ParentId = 1, Name = "Beers" },
new ProductCategory { ProductCategoryId = 4, ParentId = 1, Name = "Wines" },
new ProductCategory { ProductCategoryId = 5, ParentId = 3, Name = "Local beers" },
new ProductCategory { ProductCategoryId = 6, ParentId = 3, Name = "Foreign beers" },
new ProductCategory { ProductCategoryId = 7, ParentId = 4, Name = "Red wines" },
new ProductCategory { ProductCategoryId = 8, ParentId = 4, Name = "White wines" },
};
// todo to get below structure...
var flats = new List<ProductCategoryFlatItem>
{
new ProductCategoryFlatItem { NameWithAncestors = "Drinks", ProductCategoryId = 1 },
new ProductCategoryFlatItem { NameWithAncestors = "Drinks / Beers", ProductCategoryId = 3 },
new ProductCategoryFlatItem { NameWithAncestors = "Drinks / Beers / Local beers", ProductCategoryId = 5 },
new ProductCategoryFlatItem { NameWithAncestors = "Drinks / Beers / Foreingn beers", ProductCategoryId = 6 },
new ProductCategoryFlatItem { NameWithAncestors = "Drinks / Wines", ProductCategoryId = 4 },
new ProductCategoryFlatItem { NameWithAncestors = "Drinks / Wines / Red wines", ProductCategoryId = 7 },
new ProductCategoryFlatItem { NameWithAncestors = "Drinks / Wines / White wines", ProductCategoryId = 8 },
new ProductCategoryFlatItem { NameWithAncestors = "Food", ProductCategoryId = 2 },
};
}
}
public class ProductCategory
{
public int ProductCategoryId { get; set; }
public int? ParentId { get; set; }
public string Name { get; set; }
}
public class ProductCategoryFlatItem
{
public int ProductCategoryId { get; set; }
public string NameWithAncestors { get; set; }
}
}
UPDATE:
I successfully build a tree, and then I am trying to use tree to build breadcrumbs by searching for ancestors, see my code bellow (this is work in progress...)
public interface IProductCategoryExtensions
{
List<ProductCategoryTreeItem> BuildTreeAndGetRoots(List<ProductCategory> allCategories);
List<ProductCategoryFlatItem> CreateComboboxItems(List<ProductCategory> categories);
}
public class ProductCategoryExtensions : IProductCategoryExtensions
{
public List<ProductCategoryTreeItem> BuildTreeAndGetRoots(List<ProductCategory> allCategories)
{
var treeItems = new List<ProductCategoryTreeItem>();
var rootItems = allCategories.Where(x => x.ParentId == null);
foreach (var rootItem in rootItems)
{
treeItems.Add(new ProductCategoryTreeItem
{
Item = rootItem,
Disabled = false,
Parent = null,
Children = GetChildren(allCategories, rootItem)
});
}
return treeItems;
}
private List<ProductCategoryTreeItem> GetChildren(List<ProductCategory> allCategories, ProductCategory productCategory)
{
var children = new List<ProductCategoryTreeItem>();
var childrenTemp = allCategories.Where(x => x.ParentId == productCategory.ProductCategoryId);
foreach (var childTemp in childrenTemp)
{
var child = new ProductCategoryTreeItem
{
Disabled = false,
Item = childTemp,
Children = GetChildren(allCategories, childTemp),
};
children.Add(child);
}
return children;
}
public List<ProductCategoryFlatItem> CreateComboboxItems(List<ProductCategory> categories)
{
var flats = new List<ProductCategoryFlatItem>();
var tree = BuildTreeAndGetRoots(categories);
foreach (var treeItem in tree)
{
flats.Add(CreateFlatItem(treeItem, categories));
if (treeItem.HasChildren)
{
flats.AddRange(GetChildrenFlats(treeItem.Children));
}
}
return flats;
}
private List<ProductCategoryFlatItem> GetChildrenFlats(List<ProductCategoryTreeItem> children)
{
var flatChildren = new List<ProductCategoryFlatItem>();
foreach (var child in children)
{
//if (child.Children != null && child.Children.Count > 0)
// Get
}
return flatChildren;
}
private ProductCategoryFlatItem CreateFlatItem(ProductCategoryTreeItem treeItem, List<ProductCategory> allCategories)
{
var flat = new ProductCategoryFlatItem();
if (treeItem.Parent == null)
{
flat.Description = treeItem.Item.Description;
flat.ProductCategoryId = treeItem.Item.ProductCategoryId;
}
else
{
}
return flat;
}
public List<ProductCategoryTreeItem> BuildTreeAndGetRoots(List<ProductCategory> allCategories)
{
var treeItems = new List<ProductCategoryTreeItem>();
var rootItems = allCategories.Where(x => x.ParentId == null);
foreach (var rootItem in rootItems)
{
treeItems.Add(new ProductCategoryTreeItem
{
Item = rootItem,
Disabled = false,
Parent = null,
Children = GetChildren(allCategories, rootItem)
});
}
return treeItems;
}
}
public class ProductCategoryTreeItem
{
public ProductCategory Item { get; set; }
public bool Disabled { get; set; }
public ProductCategoryTreeItem Parent { get; set; }
public List<ProductCategoryTreeItem> Children { get; set; } = new List<ProductCategoryTreeItem>();
public bool HasChildren
{
get
{
return Children != null && Children.Count > 0;
}
}
}
Sorry this is kinda messy code, but I'll leave the refactoring to you.
Assuming we have two classes:
public class ProductCategory
{
public int ProductCategoryId { get; set; }
public int? ParentId { get; set; }
public string Name { get; set; }
public Dictionary<ProductCategory, int> AncestorsWithHierarchy { get; set; } = new Dictionary<ProductCategory, int>();
}
public class ProductCategoryFlatItem
{
public string NameWithAncestors { get; set; }
public int ProductCategoryId { get; set; }
}
I added AncestorsWithHierarchy to ProductCategory to be able to set up breadcrumb order right.
Then you can do setup a continuous search backwards among ancestors in a recursive way, while adding the hierarchy level to use it for .OrderBy()
var result = new List<ProductCategoryFlatItem>();
Func<ProductCategory, ProductCategory> FindParent = null;
FindParent = thisItem =>
{
var parent = categories.Find(c => c.ProductCategoryId == thisItem.ParentId);
return parent;
};
foreach (var category in categories)
{
int hierarchyLevel = 0;
var parent = FindParent(category);
while (parent != null)
{
category.AncestorsWithHierarchy.Add(parent, hierarchyLevel);
hierarchyLevel++;
parent = FindParent(parent);
}
// Add self since we want it in the breadcrumb
category.AncestorsWithHierarchy.Add(category, -1);
result.Add(new ProductCategoryFlatItem()
{
NameWithAncestors = string.Join(" / ", category.AncestorsWithHierarchy.OrderByDescending(x => x.Value).Select(anc => anc.Key.Name)),
ProductCategoryId = category.ProductCategoryId
});
}
Which gives you your desired result:
However, I would never do this kind of operation during every read. I'm assuming this data will be read much more than it'll be written. So, what I would really do is, to move this logic where you are CRUD'ing to the database and build your breadcrumb there as a new field, and only recalculate if a category changes. This is much better than calculating on every single read request for every single user.

LINQ query to group parent and child elements

I'm currently working on a .NET 4.7 application. I need to create a tree structure out of unsorted data.
The final tree structure looks like this:
public class LocationViewModel
{
public int Id { get; set; }
public string Code { get; set; }
public List<LocationViewModel> ChildLocations { get; set; }
}
One Parent LocationViewModel can have several ChildLocations. Each ChildLocation can have several ChildLocations itself again.
I need to sort the data from the following structure. My unsorted data is a List<LinkParentChildViewModel> LinksParentChild, and looks like this:
public class LinkParentChildViewModel
{
public Location Parent { get; set; }
public LocationLink Child { get; set; }
}
public class Location
{
public int Id { get; set; }
public string Code { get; set; }
}
public class LocationLink
{
public int ParentLocationId { get; set; }
public int ChildLocationId { get; set; }
}
First I have a List<Location> Locations, which contains all the locations.
Then I'm getting a List<LinkParentChildViewModel> LinksParentChild, the entries are all mixed up - thus a Parent can be a child and a child can be a parent.
var LinksParentChild = new List<LinkParentChildViewModel>
{
new LinkParentChildViewModel
{
Parent = new Location
{
Id = 8,
Code = "ParLoc1",
},
Child = new LocationLink
{
ChildLocationId = 4,
ParentLocationId = null
}
},
new LinkParentChildViewModel
{
Parent = new Location
{
Id = 4,
Code = "Loc1",
},
Child = new LocationLink
{
ChildLocationId = 6,
ParentLocationId = 8
}
},
new LinkParentChildViewModel
{
Parent = new Location
{
Id = 6,
Code = "ChildLoc1",
},
Child = new LocationLink
{
ChildLocationId = null,
ParentLocationId = 4
}
},
new LinkParentChildViewModel
{
Parent = new Location
{
Id = 10,
Code = "LeftLoc1",
},
Child = new LocationLink
{
ChildLocationId = 11,
ParentLocationId = 4
}
},
new LinkParentChildViewModel
{
Parent = new Location
{
Id = 11,
Code = "LeftChildLoc1",
},
Child = new LocationLink
{
ChildLocationId = null,
ParentLocationId = 10
}
}
};
I need to write a LINQ query to group all nodes from my data into a List<LocationViewModel> result.
var result = LinksParentChild.GroupBy(x => x.Parent.Id).Select(x => new LocationViewModel
{
Id = x.First().Parent.Id,
Code = x.First().Parent.Code,
ChildLocations = new List<LocationViewModel>
{
// ... I'm stuck unfortunately, somehow i need to query and group all locations
}
}).ToList();
I tried, but unfortunately I'm stuck:
I need to select all Locations like a tree structure
Do you know how to solve this issue?
Thanks a lot!
The result looks like this:
var result = new List<LocationViewModel>
{
new LocationViewModel
{
Id = 8,
Code = "ParLoc1",
ChildLocations = new List<LocationViewModel>
{
new LocationViewModel
{
Id = 4,
Code = "Loc1",
ChildLocations = new List<LocationViewModel>
{
new LocationViewModel
{
Id = 6,
Code = "ChildLoc1"
},
new LocationViewModel
{
Id = 10,
Code = "LeftLoc1",
ChildLocations = new List<LocationViewModel>
{
new LocationViewModel
{
Id = 11,
Code = "LeftChildLoc1"
}
}
}
}
}
}
}
};
you can try with Recursion
public static List<LocationViewModel> GetHierarchy(List<LinkParentChildViewModel> linkParentChildViewModels, int parentId)
{
return linkParentChildViewModels.Where(x => x.Parent.Id == parentId).Select(x => new LocationViewModel
{
Id = x.Parent.Id,
Code = x.Parent.Code,
ChildLocations = GetHierarchy(linkParentChildViewModels, x.Child.ChildLocationId)
}).ToList();
}
Call this from Main method
var result = GetHierarchy(LinksParentChild, 8);

LINQ distinct on groups of information

I have multiple items (List)
I need to get distinct features for the items but the issue is that each item has two features. So both features need to match on GroupTypeId and GroupId to become a distinct group.
I need to group items that have the same features (per above distinct groups found). I don't need features here again at the item level since I will have these per above in a separate object.
I need to keep items order intact, the first item will go in group 1, then second might go in group 1 or group 2 and so on.
Also, each item in group, item number needs to be overwritten per the new sequence in that group.
Can i do above tasks purely with LINQ rather than using nested loops?
In the below sample for items
i have 3 distinct feature groups
and 3 item groups. Item 2 and 4 needs to be grouped together and the line no needs to change to 1 and 2. For item 1 and 3, line number should become as 1.
Need to add to List whose count will be 3
Index[0] will have 2 features and 1 item
Index[1] will have 2 features and 2 items
Index[2] will have 2 features and 1 item
public class ItemPicked
{
public int Id { get; set; }
public string Description { get; set; }
public int LineNumber { get; set; }
public int PartId { get; set; }
public List<ItemFeature> Features { get; set; }
}
public class ItemFeature
{
public string OriginalReceived { get; set; }
public Group Feature { get; set; }
}
public class Group
{
public int Id { get; set; }
public string GroupTypeId { get; set; }
public string GroupId { get; set; }
public int SequenceNo { get; set; }
}
public class PickedGrouping
{
public List<ItemFeature> Features { get; set; }
public List<ItemPicked> Items { get; set; }
}
var SampleFeatures1 = new List<ItemFeature>() {
new ItemFeature {
OriginalReceived = "SomeThing",
Feature = new Group() {
Id = 1, SequenceNo = 1, GroupTypeId = "A", GroupId = "B"
}
},
new ItemFeature {
OriginalReceived = "SomeThing2",
Feature = new Group() {
Id = 2, SequenceNo = 2, GroupTypeId = "Y", GroupId = "Z"
}
}
};
var SampleFeatures2 = new List<ItemFeature>() {
new ItemFeature {
OriginalReceived = "SomeThing3",
Feature = new Group() {
Id = 3, SequenceNo = 3, GroupTypeId = "C", GroupId = "D"
}
},
new ItemFeature {
OriginalReceived = "SomeThing4",
Feature = new Group() {
Id = 4, SequenceNo = 4, GroupTypeId = "X", GroupId = "Y"
}
}
};
var SampleFeatures3 = new List<ItemFeature>() {
new ItemFeature {
OriginalReceived = "SomeThing5",
Feature = new Group() {
Id = 3, SequenceNo = 3, GroupTypeId = "C", GroupId = "D"
}
},
new ItemFeature {
OriginalReceived = "SomeThing5",
Feature = new Group() {
Id = 2, SequenceNo = 2, GroupTypeId = "M", GroupId = "K"
}
}
};
var items = new List<ItemPicked>(){
new ItemPicked{
Id = 1, Description = "Item 1", LineNumber = 1, Features = SampleFeatures1
},
new ItemPicked{
Id = 2, Description = "Item 2", LineNumber = 2, Features = SampleFeatures2
},
new ItemPicked{
Id = 3, Description = "Item 3", LineNumber = 3, Features = SampleFeatures3
},
new ItemPicked{
Id = 4, Description = "Item 4", LineNumber = 4, Features = SampleFeatures2
}
};
var pickedGroupings = new List<PickedGrouping>();
PickedGrouping selectedGroup = null;
foreach (var item in items)
{
var found = 0;
if(item.Features == null || !item.Features.Any())
{
selectedGroup = pickedGroupings.FirstOrDefault(x => x.Features == null || !x.Features.Any());
if (selectedGroup == null) selectedGroup = new PickedGrouping();
selectedGroup.Features.AddRange(item.Features);
}
else
{
foreach (var feature in item.Features)
{
foreach (var pg in pickedGroupings)
{
if ((item.Features == null || !item.Features.Any()) && (pg.Features == null || !pg.Features.Any())){
selectedGroup = pg;
found += 1;
}
else
{
foreach (var pgf in pg.Features)
{
if (pgf.Feature == null) continue;
if (pgf.Feature.GroupId == feature.Feature.GroupId && pgf.Feature.GroupTypeId == feature.Feature.GroupTypeId)
{
selectedGroup = pg;
found += 1;
}
}
}
}
}
if (found < 2)
{
pickedGroupings.Add(new PickedGrouping() { Features = item.Features });
selectedGroup = pickedGroupings[pickedGroupings.Count - 1];
}
}
//add item
if (selectedGroup.Items == null) selectedGroup.Items = new List<ItemPicked>();
selectedGroup.Items.Add(item);
}
//update line number
foreach(var pg in pickedGroupings)
{
var lineNum = 1;
foreach(var item in pg.Items)
{
item.LineNumber = lineNum;
lineNum += 1;
}
}

Flat Data to Hierarchical Model C#

I have some flat data coming from the database that looks like this:
List<FlatDataGroup> elements = new List<FlatDataGroup>()
{
new FlatDataGroup {Text = "", GroupID = 1, ParentGroupID = 0, GroupName = "Admin", UserID = 1, UserName = "John Doe"},
new FlatDataGroup {Text = "", GroupID = 1, ParentGroupID = 0, GroupName = "Admin", UserID = 2, UserName = "Jane Smith"},
new FlatDataGroup {Text = "", GroupID = 2, ParentGroupID = 1, GroupName = "Support", UserID = 3, UserName = "Johnny Support"},
new FlatDataGroup {Text = "", GroupID = 3, ParentGroupID = 2, GroupName = "SubSupport", UserID = 4, UserName = "Sub Johnny Support"},
new FlatDataGroup {Text = "", GroupID = 4, ParentGroupID = 1, GroupName = "Production", UserID = 5, UserName = "Johnny Production"}
};
I would like to convert it to this:
List<Group> model = new List<Group>
{
new Group()
{
ID = 1,
Name = "Admin",
ParentGroupID = 0,
Type = "Group",
Users = new List<User>()
{
new User()
{
ID = 1,
Name = "John Doe",
GroupID = 1,
Type = "User",
},
new User()
{
ID = 2,
Name = "Jane Smith",
GroupID = 1,
Type = "User",
},
},
Groups = new List<Group>
{
new Group()
{
ID = 2,
Name = "Support",
ParentGroupID = 1,
Type = "Group",
Users = new List<User>()
{
new User()
{
ID = 3,
Name = "Johnny Support",
GroupID = 2,
Type = "User",
}
},
Groups = new List<Group>()
{
new Group()
{
ID = 3,
Name = "SubSupport",
ParentGroupID = 2,
Type = "Group",
Users = new List<User>()
{
new User()
{
ID = 4,
Name = "Sub Johnny Support",
GroupID = 3,
Type = "User",
}
},
Groups = null
}
}
},
new Group()
{
ID = 4,
Name = "Production",
ParentGroupID = 1,
Type = "Group",
Users = new List<User>()
{
new User()
{
ID = 5,
Name = "Johnny Production",
GroupID = 4,
Type = "User",
}
},
Groups = null
}
}
}
};
which will ultimately display like this in a treeview:
+Admin (Group)
John Doe (User)
Jane Smith (User)
+Support (Group)
Johnny Support (User)
+SubSupport (Group)
Sub Johnny Support (User)
+Production (Group)
Johnny Production (User)
This is what I've come up with so far to transform the flat data into the model above:
List<Group> model = new List<Group>();
var parentGrouping = elements.GroupBy(x => x.ParentGroupID);
foreach (var parentGroup in parentGrouping)
{
var grouping = parentGroup.GroupBy(y => y.GroupID);
foreach (var group in grouping)
{
Group groupItem = new Group()
{
ID = group.FirstOrDefault().GroupID,
Name = group.FirstOrDefault().GroupName,
ParentGroupID = group.FirstOrDefault().ParentGroupID,
Type = "Group",
Users = new List<User>()
};
foreach (var user in group)
{
groupItem.Users.Add(new User()
{
ID = user.UserID,
Name = user.UserName,
GroupID = user.GroupID,
Type = "User",
});
}
model.Add(groupItem);
}
}
All my groups come out along with their children users but the hierarchy is not preserved. I think I may need to do this recursively but I can't seem to get my head around it. Any help would be greatly appreciated.
Here are the models for the sake of completeness:
public class FlatDataGroup
{
public string Text { get; set; }
public int GroupID { get; set; }
public int ParentGroupID { get; set; }
public string GroupName { get; set; }
public int UserID { get; set; }
public string UserName { get; set; }
}
public class Group
{
public int ID { get; set; }
public int ParentGroupID { get; set; }
public string Name { get; set; }
public List<Group> Groups { get; set; }
public List<User> Users { get; set; }
public string Type { get; set; }
}
public class User
{
public int ID { get; set; }
public int GroupID { get; set; }
public string Name { get; set; }
public string Type { get; set; }
}
I'd do this in 3 passes:
Create all Group classes and populate them with data other than child groups, adding them incrementally to a dictionary mapping ID to Group.
Loop through all the groups in the dictionary and add children to their parents' Groups list of children.
Return a filtered list of all groups with no parent group -- these are the root groups. (I also sorted them by ID to remove the random ordering that the dictionary will introduce.)
Thus:
public static class FlatDataGroupExtensions
{
public const string UserType = "User";
public const string GroupType = "Group";
public static List<Group> ToGroups(this IEnumerable<FlatDataGroup> elements)
{
// Allocate all groups and index by ID.
var groups = new Dictionary<int, Group>();
foreach (var element in elements)
{
Group group;
if (!groups.TryGetValue(element.GroupID, out group))
groups[element.GroupID] = (group = new Group() { ID = element.GroupID, Name = element.GroupName, ParentGroupID = element.ParentGroupID, Type = GroupType });
group.Users.Add(new User() { GroupID = element.GroupID, ID = element.UserID, Name = element.UserName, Type = UserType });
}
// Attach child groups to their parents.
foreach (var group in groups.Values)
{
Group parent;
if (groups.TryGetValue(group.ParentGroupID, out parent) && parent != group) // Second check for safety.
parent.Groups.Add(group);
}
// Return only root groups, sorted by ID.
return groups.Values.Where(g => !groups.ContainsKey(g.ParentGroupID)).OrderBy(g => g.ID).ToList();
}
}
I also modified your Group class a little to automatically allocate the lists:
public class Group
{
List<Group> groups = new List<Group>();
List<User> users = new List<User>();
public int ID { get; set; }
public int ParentGroupID { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public List<Group> Groups { get { return groups; } }
public List<User> Users { get { return users; } }
public override string ToString()
{
return string.Format("Group: ID={0}, Name={1}, Parent ID={2}, #Users={3}, #Groups={4}", ID, Name, ParentGroupID, Users.Count, Groups.Count);
}
}

Categories