using System.Collections.Generic;
using System.Threading.Tasks;
static void Main(string[] args)
var perpetualInventoryFlatList = new List<PerpetualInventoryList> {
new PerpetualInventoryList { ItemId = 1,ItemName = "Apple",ItemCode = "IT-205", StorageCategory = "Fruit"},
new PerpetualInventoryList { ItemId = 3,ItemName = "Banana",ItemCode = "IT-206", StorageCategory = "Fruit"},
new PerpetualInventoryList { ItemId = 4,ItemName = "Pinapple",ItemCode = "IT-207", StorageCategory = "Fruit"},
new PerpetualInventoryList { ItemId = 5,ItemName = "Orange",ItemCode = "IT-208", StorageCategory = "Fruit"},
new PerpetualInventoryList { ItemId = 6,ItemName = "Mango",ItemCode = "IT-209", StorageCategory = "Fruit"},
new PerpetualInventoryList { ItemId = 7,ItemName = "IT-210",ItemCode = "IT-210", StorageCategory = "Fruit"}
var result = GetFlatList<PerpetualInventoryList, PerpetualInventoryTreeListContract>(perpetualInventoryFlatList);
public static PerpetualInventoryTreeListContract GetContract(IntermediateResult intermediateResult)
var createdItem = new List<Object>();
createdItem.Add(intermediateResult.Items.FirstOrDefault());
var createdLink = new List<Object>();
createdLink.Add(intermediateResult.Links);
return new PerpetualInventoryTreeListContract();
public static Task<List<TContract>> GetFlatList<TInput, TContract>(List<TInput> items)
where TContract : IHierarchyContract<TContract>, new()
where TInput : IHierarchyData
var itemIds = items.Select(s => s.ItemId).ToList();
var otherList = new ItemLinkService().GetItemLink2(itemIds);
var data = otherList.GroupJoin(
(thisOther, thisItem) => new IntermediateResult
Items = (IEnumerable<IHierarchyData>)thisItem
.Where(i => i.Items.Any())
var list = data.SelectMany(
x => x.Items.DefaultIfEmpty(),
(x, item) => GetContract(x)).ToList();
return (System.Threading.Tasks.Task<List<TContract>>)(object)list;
public class IntermediateResult
public IHierarchyData Links { get; set; }
public IEnumerable<IHierarchyData> Items { get; set; }
public interface IHierarchyData
public interface IHierarchyContract<TContract> : IHierarchyData
string ItemName { get; set; }
public class PerpetualInventoryList : IHierarchyData
public int ItemId { get; set; }
public string ItemName { get; set; }
public string ItemCode { get; set; }
public string StorageCategory { get; set; }
public class ItemLinkList : IHierarchyData
public int ItemId { get; set; }
public int ItemLinkId { get; set; }
public int ParentItemId { get; set; }
public int ChildItemId { get; set; }
public class PerpetualInventoryTreeListContract : IHierarchyContract<PerpetualInventoryTreeListContract>
public int ItemId { get; set; }
public string ItemName { get; set; }
public string ItemCode { get; set; }
public string StorageCategory { get; set; }
public int ItemLinkId { get; set; }
public int ParentItemId { get; set; }
public int ChildItemId { get; set; }
public class ItemLinkService
public IEnumerable<IHierarchyData> GetItemLink(IEnumerable<int> itemIds)
return new List<IHierarchyData> {
new PerpetualInventoryTreeListContract { ItemId = 1, ItemName = "First"},
new PerpetualInventoryTreeListContract { ItemId = 2, ItemName = "Second"},
new PerpetualInventoryTreeListContract { ItemId = 3, ItemName = "Third"}
public IEnumerable<IHierarchyData> GetItemLink2(IEnumerable<int> itemIds)
return new List<IHierarchyData> {
new ItemLinkList { ItemId = 1,ItemLinkId = 10 , ChildItemId = 1 , ParentItemId = 2 },
new ItemLinkList { ItemId = 2,ItemLinkId = 20 , ChildItemId = 2 , ParentItemId = 4 },
new ItemLinkList { ItemId = 3,ItemLinkId = 30 , ChildItemId = 3 , ParentItemId = 2 },
new ItemLinkList { ItemId = 4,ItemLinkId = 40 , ChildItemId = 4 , ParentItemId = 0 },
new ItemLinkList { ItemId = 5,ItemLinkId = 50 , ChildItemId = 5 , ParentItemId = 3 },
new ItemLinkList { ItemId = 6,ItemLinkId = 60 , ChildItemId = 6 , ParentItemId = 3 },
new ItemLinkList { ItemId = 7,ItemLinkId = 70 , ChildItemId = 7 , ParentItemId = 3 },