Дерево иерархии с продажей группы рассчитать
У меня есть веб-приложение MLM ASP.NET MVC, которое должно отображать элементы в иерархическом представлении с их общей продажей группы.
групповая распродажа = сумма для всех детей (детская групповая распродажа + детская распродажа).
Я выполнил рекурсивный метод, который позволяет выдавать список всех дочерних элементов в иерархическом списке, но я не могу найти хороший способ рассчитать общую продажу группы, для моей текущей реализации я вычисляю групповую продажу после того, как получу список иерархии.
Это займет около 24 секунд, чтобы завершить для первого узла.
Изменение на Parallel.ForEach
займет около 16 секунд для того же узла.
Я думаю, что я определенно упустил что-то важное, чтобы рассчитать общую стоимость продажи группы У кого-нибудь есть подсказка? Ценю любые предложения и мнения. Благодарю.
Вот моя реализация.
// members, all member record
// network, consist information with parentId and childrenId
// tradeAccount, product member purchased. Group sale is sum from here
public MemberNetworkViewModel GetDownLine(List<Member> members, int memberId)
{
var member = members.FirstOrDefault(x => x.Id == memberId);
if (member == null) return null;
int count = 0;
int maxLevel = 0;
// default upline for first node
var upline = new Member() { Id = 0 };
var network = new Network() { BaseLevel = 0, NetworkLevel = 0 };
if (member.Networks.Count != 0)
{
network = member.Networks.FirstOrDefault();
// Member1 refer to upline
upline = member.Networks.FirstOrDefault().Member1;
}
var memberTree = new MemberNetworkViewModel()
{
MemberGenerationNumber = 0,
MemberId = member.Id,
MemberName = member.Username,
UplineMemberName = upline.Username,
UplineMemberId = upline.Id,
children = GetChildren(member, members, count + 1, ref maxLevel)
};
// after all children get, calculate group sale
memberTree.TotalGroupSale = NewNetworkDataHelper.GetNetworkTotalGroupSale(memberTree, members);
memberTree.children = CalculateGroupSale(memberTree.children, members);
return memberTree;
}
private List<MemberNetworkViewModel> GetChildren(Member member, List<Member> members, int count, ref int maxLevel)
{
maxLevel = count;
var downLines = new List<MemberNetworkViewModel>();
var downLineNetworks = member.Networks1.ToList();
foreach (var network in downLineNetworks)
{
var downLineMember = members.FirstOrDefault(x => x.Id == network.ChildrenMemberId);
if (downLineMember == null) continue;
AddDownlineMemberNetworkViewModel(members, count, ref maxLevel, downLines,
downLineMember);
}
return downLines;
}
private List<MemberNetworkViewModel> CalculateGroupSale(List<MemberNetworkViewModel> memberNetworkViewModels, List<Member> members)
{
//Parallel version take 16sec for first node
Parallel.ForEach((memberNetworkViewModels), memberNetworkViewModel =>
{
memberNetworkViewModel.TotalGroupSale =
NewNetworkDataHelper.GetNetworkTotalGroupSale(memberNetworkViewModel, members);
memberNetworkViewModel.children =
CalculateGroupSale(memberNetworkViewModel.children, members);
});
// foreach version take 24sec for first node
//foreach (var memberNetworkViewModel in memberNetworkViewModels)
//{
// memberNetworkViewModel.TotalGroupSale = NewNetworkDataHelper.GetNetworkTotalGroupSale(memberNetworkViewModel, members);
// memberNetworkViewModel.children = CalculateGroupSale(memberNetworkViewModel.children, members);
//}
return memberNetworkViewModels;
}
public static decimal GetNetworkTotalGroupSale(MemberNetworkViewModel memberNetworkVideModel, List<Member> members)
{
var flatternChildren = Flatten(memberNetworkVideModel);
var totalGroupSale = (decimal)0;
foreach (var memberNetworkViewModel in flatternChildren)
{
var member = members.FirstOrDefault(x => x.Id == memberNetworkViewModel.MemberId);
var filterTradeAccounts = member.TradeAccounts
.Where(x => x.Status.Equals('Active')).ToList();
totalGroupSale = totalGroupSale +
filterTradeAccounts.Sum(filterTradeAccount => filterTradeAccount
.Amount);
}
return totalGroupSale;
}
private static List<MemberNetworkViewModel> Flatten(
MemberNetworkViewModel memberNetworkViewModel)
{
var flattened = new List<MemberNetworkViewModel>() { memberNetworkViewModel };
var childrens = memberNetworkViewModel.children;
foreach (var children in childrens)
{
flattened.AddRange(Flatten(children));
}
return flattened;
}