Redundant code that needs to be refactored












-3












$begingroup$


I am writing logic in C# that contains two methods. One returns ILookup and the other returns List. Both these methods are defined in the data access layer. Some part of code need the ILookup while some need List. I feel there is redundant code and could be refactored. Looking for suggestions.



Data access layer



 ILookup<string, FIRMWIDE_MANAGER_ALLOCATION> IPackageRepo.GetManagerAllocationsGrouped(EntityType entity, int id, DateTime date, int? count)
{
var allocations = GetManagerAllocations(entity, id, date).OrderByDescending(o=> o.UsdEmv).ToList();

var allocationsLookup = allocations.ToLookup(a => a.MANAGER_STRATEGY_NAME, a => a);

// add grouping by entity
var allocationsGrouped = GroupManagerAllocationsByEntity(entity, allocations);


var strategyTotals = allocationsGrouped.GroupBy(mgrStrat => new { mgrStrat.MANAGER_STRATEGY_ID }).Select(s => new { MANAGER_STRATEGY_ID = s.Key.MANAGER_STRATEGY_ID, StrategyTotal = s.Sum(x => x.UsdEmv) }).ToDictionary(k => k.MANAGER_STRATEGY_ID, v => v.StrategyTotal);

var sum = allocationsGrouped.Sum(a => a.EMV);


foreach (IGrouping<string, FIRMWIDE_MANAGER_ALLOCATION> item in allocationsLookup)
{

var allocationsGroup = item.Select(a => a);

foreach (var alloc in allocationsGroup)
{
if (sum > 0 && strategyTotals[alloc.MANAGER_STRATEGY_ID] != 0)
{
alloc.Percent = alloc.EMV / sum;
alloc.GroupPercent = (alloc.EMV / strategyTotals[alloc.MANAGER_STRATEGY_ID]) * 100 ;

}
}
}


return allocationsLookup;
}

public List<Core.Model.FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped1(EntityType entity, int id, DateTime date, int? count = null)
{
var allocations = GetManagerAllocations(entity, id, date);
// add grouping by entity
var allocationsGrouped = GroupManagerAllocationsByEntity(entity, allocations);

var strategyTotals = allocationsGrouped.GroupBy(mgrStrat => new { mgrStrat.MANAGER_STRATEGY_ID }).Select(s => new { MANAGER_STRATEGY_ID = s.Key.MANAGER_STRATEGY_ID, StrategyTotal = s.Sum(x => x.UsdEmv) }).ToDictionary(k => k.MANAGER_STRATEGY_ID, v => v.StrategyTotal);

var sum = allocationsGrouped.Sum(a => a.EMV);
foreach (var alloc in allocationsGrouped)
{
if (sum > 0 && strategyTotals[alloc.MANAGER_STRATEGY_ID] != 0)
{
alloc.Percent = alloc.EMV / sum;
alloc.GroupPercent = alloc.EMV / strategyTotals[alloc.MANAGER_STRATEGY_ID];

}
}

return allocationsGrouped;
}


Methods in the controller that references the above



 protected IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> GetAllocationsCalculateOther(EntityType entity, int id, DateTime date)
{
var results = GetAllocationsGrouped1(entity, id, date);

results = results.GroupBy(grp => new { grp.FIRM_ID, grp.FIRM_NAME, grp.PRODUCT_ID, grp.PRODUCT_NAME })
.Select(s => new FIRMWIDE_MANAGER_ALLOCATION
{
FIRM_ID = s.Key.FIRM_ID,
FIRM_NAME = s.Key.FIRM_NAME,
PRODUCT_ID = s.Key.PRODUCT_ID,
PRODUCT_NAME = s.Key.PRODUCT_NAME,
EMV = s.Sum(x => x.EMV),
USD_EMV = s.Sum(x => x.USD_EMV),
Percent = s.Sum(x => x.Percent),
}
);

var resultsWithOthers = new List<FIRMWIDE_MANAGER_ALLOCATION>();
var cutOff = 14;
if (results != null && results.Count() > cutOff)
{
//var cutOff = results.Count() - (results.Count() / 3);
results = results.OrderByDescending(x => x.EMV);
resultsWithOthers = results.Take(cutOff).ToList();
var otherSum = results.Skip(cutOff).Sum(x => x.EMV);
var sum = results.Sum(x => x.EMV);
var otherPercent = sum > 0 ? otherSum / sum : 0;
resultsWithOthers.Add(new FIRMWIDE_MANAGER_ALLOCATION { PRODUCT_NAME = "Other", USD_EMV = otherSum, Percent = otherPercent });
}
else
resultsWithOthers = results.ToList();

return resultsWithOthers;
}


public HttpResponseMessage DownloadFundAllocationDetails(int id, DateTime date)
{
var ms = GetStrategy(id);

DateTime d = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
if (ms.FIRM_ID != null)
{
var firm = GetService<FIRM>().Get(ms.FIRM_ID.Value);
IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> allocationsGroup = null;
var allocationsGrouped = GetAllocationsGrouped(EntityType.Firm, firm.ID, d);


string fileName = string.Format("{0} as of {1}.xlsx", "test",
date.ToString("MMM, yyyy"));
byte fileContents;
var newFile = new FileInfo(fileName);
using (var package = new OfficeOpenXml.ExcelPackage(newFile))
{
FundAllocationsPrinter.Print(package, allocationsGrouped);
fileContents = package.GetAsByteArray();
}


var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(fileContents)
};

result.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};

result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

return result;
}

return null;

#endregion
}


private AllocationsViewModel GetAllocationsViewModel(int id, DateTime date)
{

var ms = GetStrategy(id);

DateTime d = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
if (ms.FIRM_ID != null)
{
var firm = GetService<FIRM>().Get(ms.FIRM_ID.Value);
var currentEntity = new EntityAllocationsViewModel(new EntityViewModel { EntityId = firm.ID, EntityName = firm.NAME, EntityType = EntityType.Firm });
//var allocationsGrouped = Mapper.Map<List<FIRMWIDE_MANAGER_ALLOCATION>, List<FirmWideAllocationsViewModel>>(GetAllocationsGrouped(EntityType.Firm, firm.ID, d).ToList());

//Mapper.Map<ILookup<string,FIRMWIDE_MANAGER_ALLOCATION>,ILookup<string,FirmWideAllocationsViewModel>>((ILookup<string, FIRMWIDE_MANAGER_ALLOCATION>)

var allocationsGrouped = GetAllocationsGrouped(EntityType.Firm, firm.ID, d);

var result = new List<FirmWideAllocationsViewModel>();

foreach (var ag in allocationsGrouped)
{
var allocationsGroup = ag.Select(a => a).OrderByDescending(o=> o.UsdEmv ) ;

CreateHierarchy(ag.Key, allocationsGroup, result);
}

var missingProducts = Mapper.Map<List<MISSING_PRODUCT>, List<MissingProductsViewModel>>(GetMissingProducts()).GroupBy(a => a.ProductType);

var vm = new AllocationsViewModel
{
CurrentEntity = currentEntity,
ManagerAllocations = result,
MissingProducts = missingProducts
};

return vm;
}

return null;
}


Interface



 public interface IPackageRepo {

ILookup<string, FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped(EntityType entity, int id, DateTime date, int? count = null);
IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped1(EntityType entity, int id, DateTime date, int? count = null);
}









share|improve this question











$endgroup$

















    -3












    $begingroup$


    I am writing logic in C# that contains two methods. One returns ILookup and the other returns List. Both these methods are defined in the data access layer. Some part of code need the ILookup while some need List. I feel there is redundant code and could be refactored. Looking for suggestions.



    Data access layer



     ILookup<string, FIRMWIDE_MANAGER_ALLOCATION> IPackageRepo.GetManagerAllocationsGrouped(EntityType entity, int id, DateTime date, int? count)
    {
    var allocations = GetManagerAllocations(entity, id, date).OrderByDescending(o=> o.UsdEmv).ToList();

    var allocationsLookup = allocations.ToLookup(a => a.MANAGER_STRATEGY_NAME, a => a);

    // add grouping by entity
    var allocationsGrouped = GroupManagerAllocationsByEntity(entity, allocations);


    var strategyTotals = allocationsGrouped.GroupBy(mgrStrat => new { mgrStrat.MANAGER_STRATEGY_ID }).Select(s => new { MANAGER_STRATEGY_ID = s.Key.MANAGER_STRATEGY_ID, StrategyTotal = s.Sum(x => x.UsdEmv) }).ToDictionary(k => k.MANAGER_STRATEGY_ID, v => v.StrategyTotal);

    var sum = allocationsGrouped.Sum(a => a.EMV);


    foreach (IGrouping<string, FIRMWIDE_MANAGER_ALLOCATION> item in allocationsLookup)
    {

    var allocationsGroup = item.Select(a => a);

    foreach (var alloc in allocationsGroup)
    {
    if (sum > 0 && strategyTotals[alloc.MANAGER_STRATEGY_ID] != 0)
    {
    alloc.Percent = alloc.EMV / sum;
    alloc.GroupPercent = (alloc.EMV / strategyTotals[alloc.MANAGER_STRATEGY_ID]) * 100 ;

    }
    }
    }


    return allocationsLookup;
    }

    public List<Core.Model.FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped1(EntityType entity, int id, DateTime date, int? count = null)
    {
    var allocations = GetManagerAllocations(entity, id, date);
    // add grouping by entity
    var allocationsGrouped = GroupManagerAllocationsByEntity(entity, allocations);

    var strategyTotals = allocationsGrouped.GroupBy(mgrStrat => new { mgrStrat.MANAGER_STRATEGY_ID }).Select(s => new { MANAGER_STRATEGY_ID = s.Key.MANAGER_STRATEGY_ID, StrategyTotal = s.Sum(x => x.UsdEmv) }).ToDictionary(k => k.MANAGER_STRATEGY_ID, v => v.StrategyTotal);

    var sum = allocationsGrouped.Sum(a => a.EMV);
    foreach (var alloc in allocationsGrouped)
    {
    if (sum > 0 && strategyTotals[alloc.MANAGER_STRATEGY_ID] != 0)
    {
    alloc.Percent = alloc.EMV / sum;
    alloc.GroupPercent = alloc.EMV / strategyTotals[alloc.MANAGER_STRATEGY_ID];

    }
    }

    return allocationsGrouped;
    }


    Methods in the controller that references the above



     protected IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> GetAllocationsCalculateOther(EntityType entity, int id, DateTime date)
    {
    var results = GetAllocationsGrouped1(entity, id, date);

    results = results.GroupBy(grp => new { grp.FIRM_ID, grp.FIRM_NAME, grp.PRODUCT_ID, grp.PRODUCT_NAME })
    .Select(s => new FIRMWIDE_MANAGER_ALLOCATION
    {
    FIRM_ID = s.Key.FIRM_ID,
    FIRM_NAME = s.Key.FIRM_NAME,
    PRODUCT_ID = s.Key.PRODUCT_ID,
    PRODUCT_NAME = s.Key.PRODUCT_NAME,
    EMV = s.Sum(x => x.EMV),
    USD_EMV = s.Sum(x => x.USD_EMV),
    Percent = s.Sum(x => x.Percent),
    }
    );

    var resultsWithOthers = new List<FIRMWIDE_MANAGER_ALLOCATION>();
    var cutOff = 14;
    if (results != null && results.Count() > cutOff)
    {
    //var cutOff = results.Count() - (results.Count() / 3);
    results = results.OrderByDescending(x => x.EMV);
    resultsWithOthers = results.Take(cutOff).ToList();
    var otherSum = results.Skip(cutOff).Sum(x => x.EMV);
    var sum = results.Sum(x => x.EMV);
    var otherPercent = sum > 0 ? otherSum / sum : 0;
    resultsWithOthers.Add(new FIRMWIDE_MANAGER_ALLOCATION { PRODUCT_NAME = "Other", USD_EMV = otherSum, Percent = otherPercent });
    }
    else
    resultsWithOthers = results.ToList();

    return resultsWithOthers;
    }


    public HttpResponseMessage DownloadFundAllocationDetails(int id, DateTime date)
    {
    var ms = GetStrategy(id);

    DateTime d = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
    if (ms.FIRM_ID != null)
    {
    var firm = GetService<FIRM>().Get(ms.FIRM_ID.Value);
    IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> allocationsGroup = null;
    var allocationsGrouped = GetAllocationsGrouped(EntityType.Firm, firm.ID, d);


    string fileName = string.Format("{0} as of {1}.xlsx", "test",
    date.ToString("MMM, yyyy"));
    byte fileContents;
    var newFile = new FileInfo(fileName);
    using (var package = new OfficeOpenXml.ExcelPackage(newFile))
    {
    FundAllocationsPrinter.Print(package, allocationsGrouped);
    fileContents = package.GetAsByteArray();
    }


    var result = new HttpResponseMessage(HttpStatusCode.OK)
    {
    Content = new ByteArrayContent(fileContents)
    };

    result.Content.Headers.ContentDisposition =
    new ContentDispositionHeaderValue("attachment")
    {
    FileName = fileName
    };

    result.Content.Headers.ContentType =
    new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

    return result;
    }

    return null;

    #endregion
    }


    private AllocationsViewModel GetAllocationsViewModel(int id, DateTime date)
    {

    var ms = GetStrategy(id);

    DateTime d = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
    if (ms.FIRM_ID != null)
    {
    var firm = GetService<FIRM>().Get(ms.FIRM_ID.Value);
    var currentEntity = new EntityAllocationsViewModel(new EntityViewModel { EntityId = firm.ID, EntityName = firm.NAME, EntityType = EntityType.Firm });
    //var allocationsGrouped = Mapper.Map<List<FIRMWIDE_MANAGER_ALLOCATION>, List<FirmWideAllocationsViewModel>>(GetAllocationsGrouped(EntityType.Firm, firm.ID, d).ToList());

    //Mapper.Map<ILookup<string,FIRMWIDE_MANAGER_ALLOCATION>,ILookup<string,FirmWideAllocationsViewModel>>((ILookup<string, FIRMWIDE_MANAGER_ALLOCATION>)

    var allocationsGrouped = GetAllocationsGrouped(EntityType.Firm, firm.ID, d);

    var result = new List<FirmWideAllocationsViewModel>();

    foreach (var ag in allocationsGrouped)
    {
    var allocationsGroup = ag.Select(a => a).OrderByDescending(o=> o.UsdEmv ) ;

    CreateHierarchy(ag.Key, allocationsGroup, result);
    }

    var missingProducts = Mapper.Map<List<MISSING_PRODUCT>, List<MissingProductsViewModel>>(GetMissingProducts()).GroupBy(a => a.ProductType);

    var vm = new AllocationsViewModel
    {
    CurrentEntity = currentEntity,
    ManagerAllocations = result,
    MissingProducts = missingProducts
    };

    return vm;
    }

    return null;
    }


    Interface



     public interface IPackageRepo {

    ILookup<string, FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped(EntityType entity, int id, DateTime date, int? count = null);
    IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped1(EntityType entity, int id, DateTime date, int? count = null);
    }









    share|improve this question











    $endgroup$















      -3












      -3








      -3





      $begingroup$


      I am writing logic in C# that contains two methods. One returns ILookup and the other returns List. Both these methods are defined in the data access layer. Some part of code need the ILookup while some need List. I feel there is redundant code and could be refactored. Looking for suggestions.



      Data access layer



       ILookup<string, FIRMWIDE_MANAGER_ALLOCATION> IPackageRepo.GetManagerAllocationsGrouped(EntityType entity, int id, DateTime date, int? count)
      {
      var allocations = GetManagerAllocations(entity, id, date).OrderByDescending(o=> o.UsdEmv).ToList();

      var allocationsLookup = allocations.ToLookup(a => a.MANAGER_STRATEGY_NAME, a => a);

      // add grouping by entity
      var allocationsGrouped = GroupManagerAllocationsByEntity(entity, allocations);


      var strategyTotals = allocationsGrouped.GroupBy(mgrStrat => new { mgrStrat.MANAGER_STRATEGY_ID }).Select(s => new { MANAGER_STRATEGY_ID = s.Key.MANAGER_STRATEGY_ID, StrategyTotal = s.Sum(x => x.UsdEmv) }).ToDictionary(k => k.MANAGER_STRATEGY_ID, v => v.StrategyTotal);

      var sum = allocationsGrouped.Sum(a => a.EMV);


      foreach (IGrouping<string, FIRMWIDE_MANAGER_ALLOCATION> item in allocationsLookup)
      {

      var allocationsGroup = item.Select(a => a);

      foreach (var alloc in allocationsGroup)
      {
      if (sum > 0 && strategyTotals[alloc.MANAGER_STRATEGY_ID] != 0)
      {
      alloc.Percent = alloc.EMV / sum;
      alloc.GroupPercent = (alloc.EMV / strategyTotals[alloc.MANAGER_STRATEGY_ID]) * 100 ;

      }
      }
      }


      return allocationsLookup;
      }

      public List<Core.Model.FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped1(EntityType entity, int id, DateTime date, int? count = null)
      {
      var allocations = GetManagerAllocations(entity, id, date);
      // add grouping by entity
      var allocationsGrouped = GroupManagerAllocationsByEntity(entity, allocations);

      var strategyTotals = allocationsGrouped.GroupBy(mgrStrat => new { mgrStrat.MANAGER_STRATEGY_ID }).Select(s => new { MANAGER_STRATEGY_ID = s.Key.MANAGER_STRATEGY_ID, StrategyTotal = s.Sum(x => x.UsdEmv) }).ToDictionary(k => k.MANAGER_STRATEGY_ID, v => v.StrategyTotal);

      var sum = allocationsGrouped.Sum(a => a.EMV);
      foreach (var alloc in allocationsGrouped)
      {
      if (sum > 0 && strategyTotals[alloc.MANAGER_STRATEGY_ID] != 0)
      {
      alloc.Percent = alloc.EMV / sum;
      alloc.GroupPercent = alloc.EMV / strategyTotals[alloc.MANAGER_STRATEGY_ID];

      }
      }

      return allocationsGrouped;
      }


      Methods in the controller that references the above



       protected IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> GetAllocationsCalculateOther(EntityType entity, int id, DateTime date)
      {
      var results = GetAllocationsGrouped1(entity, id, date);

      results = results.GroupBy(grp => new { grp.FIRM_ID, grp.FIRM_NAME, grp.PRODUCT_ID, grp.PRODUCT_NAME })
      .Select(s => new FIRMWIDE_MANAGER_ALLOCATION
      {
      FIRM_ID = s.Key.FIRM_ID,
      FIRM_NAME = s.Key.FIRM_NAME,
      PRODUCT_ID = s.Key.PRODUCT_ID,
      PRODUCT_NAME = s.Key.PRODUCT_NAME,
      EMV = s.Sum(x => x.EMV),
      USD_EMV = s.Sum(x => x.USD_EMV),
      Percent = s.Sum(x => x.Percent),
      }
      );

      var resultsWithOthers = new List<FIRMWIDE_MANAGER_ALLOCATION>();
      var cutOff = 14;
      if (results != null && results.Count() > cutOff)
      {
      //var cutOff = results.Count() - (results.Count() / 3);
      results = results.OrderByDescending(x => x.EMV);
      resultsWithOthers = results.Take(cutOff).ToList();
      var otherSum = results.Skip(cutOff).Sum(x => x.EMV);
      var sum = results.Sum(x => x.EMV);
      var otherPercent = sum > 0 ? otherSum / sum : 0;
      resultsWithOthers.Add(new FIRMWIDE_MANAGER_ALLOCATION { PRODUCT_NAME = "Other", USD_EMV = otherSum, Percent = otherPercent });
      }
      else
      resultsWithOthers = results.ToList();

      return resultsWithOthers;
      }


      public HttpResponseMessage DownloadFundAllocationDetails(int id, DateTime date)
      {
      var ms = GetStrategy(id);

      DateTime d = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
      if (ms.FIRM_ID != null)
      {
      var firm = GetService<FIRM>().Get(ms.FIRM_ID.Value);
      IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> allocationsGroup = null;
      var allocationsGrouped = GetAllocationsGrouped(EntityType.Firm, firm.ID, d);


      string fileName = string.Format("{0} as of {1}.xlsx", "test",
      date.ToString("MMM, yyyy"));
      byte fileContents;
      var newFile = new FileInfo(fileName);
      using (var package = new OfficeOpenXml.ExcelPackage(newFile))
      {
      FundAllocationsPrinter.Print(package, allocationsGrouped);
      fileContents = package.GetAsByteArray();
      }


      var result = new HttpResponseMessage(HttpStatusCode.OK)
      {
      Content = new ByteArrayContent(fileContents)
      };

      result.Content.Headers.ContentDisposition =
      new ContentDispositionHeaderValue("attachment")
      {
      FileName = fileName
      };

      result.Content.Headers.ContentType =
      new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

      return result;
      }

      return null;

      #endregion
      }


      private AllocationsViewModel GetAllocationsViewModel(int id, DateTime date)
      {

      var ms = GetStrategy(id);

      DateTime d = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
      if (ms.FIRM_ID != null)
      {
      var firm = GetService<FIRM>().Get(ms.FIRM_ID.Value);
      var currentEntity = new EntityAllocationsViewModel(new EntityViewModel { EntityId = firm.ID, EntityName = firm.NAME, EntityType = EntityType.Firm });
      //var allocationsGrouped = Mapper.Map<List<FIRMWIDE_MANAGER_ALLOCATION>, List<FirmWideAllocationsViewModel>>(GetAllocationsGrouped(EntityType.Firm, firm.ID, d).ToList());

      //Mapper.Map<ILookup<string,FIRMWIDE_MANAGER_ALLOCATION>,ILookup<string,FirmWideAllocationsViewModel>>((ILookup<string, FIRMWIDE_MANAGER_ALLOCATION>)

      var allocationsGrouped = GetAllocationsGrouped(EntityType.Firm, firm.ID, d);

      var result = new List<FirmWideAllocationsViewModel>();

      foreach (var ag in allocationsGrouped)
      {
      var allocationsGroup = ag.Select(a => a).OrderByDescending(o=> o.UsdEmv ) ;

      CreateHierarchy(ag.Key, allocationsGroup, result);
      }

      var missingProducts = Mapper.Map<List<MISSING_PRODUCT>, List<MissingProductsViewModel>>(GetMissingProducts()).GroupBy(a => a.ProductType);

      var vm = new AllocationsViewModel
      {
      CurrentEntity = currentEntity,
      ManagerAllocations = result,
      MissingProducts = missingProducts
      };

      return vm;
      }

      return null;
      }


      Interface



       public interface IPackageRepo {

      ILookup<string, FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped(EntityType entity, int id, DateTime date, int? count = null);
      IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped1(EntityType entity, int id, DateTime date, int? count = null);
      }









      share|improve this question











      $endgroup$




      I am writing logic in C# that contains two methods. One returns ILookup and the other returns List. Both these methods are defined in the data access layer. Some part of code need the ILookup while some need List. I feel there is redundant code and could be refactored. Looking for suggestions.



      Data access layer



       ILookup<string, FIRMWIDE_MANAGER_ALLOCATION> IPackageRepo.GetManagerAllocationsGrouped(EntityType entity, int id, DateTime date, int? count)
      {
      var allocations = GetManagerAllocations(entity, id, date).OrderByDescending(o=> o.UsdEmv).ToList();

      var allocationsLookup = allocations.ToLookup(a => a.MANAGER_STRATEGY_NAME, a => a);

      // add grouping by entity
      var allocationsGrouped = GroupManagerAllocationsByEntity(entity, allocations);


      var strategyTotals = allocationsGrouped.GroupBy(mgrStrat => new { mgrStrat.MANAGER_STRATEGY_ID }).Select(s => new { MANAGER_STRATEGY_ID = s.Key.MANAGER_STRATEGY_ID, StrategyTotal = s.Sum(x => x.UsdEmv) }).ToDictionary(k => k.MANAGER_STRATEGY_ID, v => v.StrategyTotal);

      var sum = allocationsGrouped.Sum(a => a.EMV);


      foreach (IGrouping<string, FIRMWIDE_MANAGER_ALLOCATION> item in allocationsLookup)
      {

      var allocationsGroup = item.Select(a => a);

      foreach (var alloc in allocationsGroup)
      {
      if (sum > 0 && strategyTotals[alloc.MANAGER_STRATEGY_ID] != 0)
      {
      alloc.Percent = alloc.EMV / sum;
      alloc.GroupPercent = (alloc.EMV / strategyTotals[alloc.MANAGER_STRATEGY_ID]) * 100 ;

      }
      }
      }


      return allocationsLookup;
      }

      public List<Core.Model.FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped1(EntityType entity, int id, DateTime date, int? count = null)
      {
      var allocations = GetManagerAllocations(entity, id, date);
      // add grouping by entity
      var allocationsGrouped = GroupManagerAllocationsByEntity(entity, allocations);

      var strategyTotals = allocationsGrouped.GroupBy(mgrStrat => new { mgrStrat.MANAGER_STRATEGY_ID }).Select(s => new { MANAGER_STRATEGY_ID = s.Key.MANAGER_STRATEGY_ID, StrategyTotal = s.Sum(x => x.UsdEmv) }).ToDictionary(k => k.MANAGER_STRATEGY_ID, v => v.StrategyTotal);

      var sum = allocationsGrouped.Sum(a => a.EMV);
      foreach (var alloc in allocationsGrouped)
      {
      if (sum > 0 && strategyTotals[alloc.MANAGER_STRATEGY_ID] != 0)
      {
      alloc.Percent = alloc.EMV / sum;
      alloc.GroupPercent = alloc.EMV / strategyTotals[alloc.MANAGER_STRATEGY_ID];

      }
      }

      return allocationsGrouped;
      }


      Methods in the controller that references the above



       protected IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> GetAllocationsCalculateOther(EntityType entity, int id, DateTime date)
      {
      var results = GetAllocationsGrouped1(entity, id, date);

      results = results.GroupBy(grp => new { grp.FIRM_ID, grp.FIRM_NAME, grp.PRODUCT_ID, grp.PRODUCT_NAME })
      .Select(s => new FIRMWIDE_MANAGER_ALLOCATION
      {
      FIRM_ID = s.Key.FIRM_ID,
      FIRM_NAME = s.Key.FIRM_NAME,
      PRODUCT_ID = s.Key.PRODUCT_ID,
      PRODUCT_NAME = s.Key.PRODUCT_NAME,
      EMV = s.Sum(x => x.EMV),
      USD_EMV = s.Sum(x => x.USD_EMV),
      Percent = s.Sum(x => x.Percent),
      }
      );

      var resultsWithOthers = new List<FIRMWIDE_MANAGER_ALLOCATION>();
      var cutOff = 14;
      if (results != null && results.Count() > cutOff)
      {
      //var cutOff = results.Count() - (results.Count() / 3);
      results = results.OrderByDescending(x => x.EMV);
      resultsWithOthers = results.Take(cutOff).ToList();
      var otherSum = results.Skip(cutOff).Sum(x => x.EMV);
      var sum = results.Sum(x => x.EMV);
      var otherPercent = sum > 0 ? otherSum / sum : 0;
      resultsWithOthers.Add(new FIRMWIDE_MANAGER_ALLOCATION { PRODUCT_NAME = "Other", USD_EMV = otherSum, Percent = otherPercent });
      }
      else
      resultsWithOthers = results.ToList();

      return resultsWithOthers;
      }


      public HttpResponseMessage DownloadFundAllocationDetails(int id, DateTime date)
      {
      var ms = GetStrategy(id);

      DateTime d = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
      if (ms.FIRM_ID != null)
      {
      var firm = GetService<FIRM>().Get(ms.FIRM_ID.Value);
      IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> allocationsGroup = null;
      var allocationsGrouped = GetAllocationsGrouped(EntityType.Firm, firm.ID, d);


      string fileName = string.Format("{0} as of {1}.xlsx", "test",
      date.ToString("MMM, yyyy"));
      byte fileContents;
      var newFile = new FileInfo(fileName);
      using (var package = new OfficeOpenXml.ExcelPackage(newFile))
      {
      FundAllocationsPrinter.Print(package, allocationsGrouped);
      fileContents = package.GetAsByteArray();
      }


      var result = new HttpResponseMessage(HttpStatusCode.OK)
      {
      Content = new ByteArrayContent(fileContents)
      };

      result.Content.Headers.ContentDisposition =
      new ContentDispositionHeaderValue("attachment")
      {
      FileName = fileName
      };

      result.Content.Headers.ContentType =
      new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

      return result;
      }

      return null;

      #endregion
      }


      private AllocationsViewModel GetAllocationsViewModel(int id, DateTime date)
      {

      var ms = GetStrategy(id);

      DateTime d = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
      if (ms.FIRM_ID != null)
      {
      var firm = GetService<FIRM>().Get(ms.FIRM_ID.Value);
      var currentEntity = new EntityAllocationsViewModel(new EntityViewModel { EntityId = firm.ID, EntityName = firm.NAME, EntityType = EntityType.Firm });
      //var allocationsGrouped = Mapper.Map<List<FIRMWIDE_MANAGER_ALLOCATION>, List<FirmWideAllocationsViewModel>>(GetAllocationsGrouped(EntityType.Firm, firm.ID, d).ToList());

      //Mapper.Map<ILookup<string,FIRMWIDE_MANAGER_ALLOCATION>,ILookup<string,FirmWideAllocationsViewModel>>((ILookup<string, FIRMWIDE_MANAGER_ALLOCATION>)

      var allocationsGrouped = GetAllocationsGrouped(EntityType.Firm, firm.ID, d);

      var result = new List<FirmWideAllocationsViewModel>();

      foreach (var ag in allocationsGrouped)
      {
      var allocationsGroup = ag.Select(a => a).OrderByDescending(o=> o.UsdEmv ) ;

      CreateHierarchy(ag.Key, allocationsGroup, result);
      }

      var missingProducts = Mapper.Map<List<MISSING_PRODUCT>, List<MissingProductsViewModel>>(GetMissingProducts()).GroupBy(a => a.ProductType);

      var vm = new AllocationsViewModel
      {
      CurrentEntity = currentEntity,
      ManagerAllocations = result,
      MissingProducts = missingProducts
      };

      return vm;
      }

      return null;
      }


      Interface



       public interface IPackageRepo {

      ILookup<string, FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped(EntityType entity, int id, DateTime date, int? count = null);
      IEnumerable<FIRMWIDE_MANAGER_ALLOCATION> GetManagerAllocationsGrouped1(EntityType entity, int id, DateTime date, int? count = null);
      }






      c#






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 1 hour ago









      esote

      2,78611038




      2,78611038










      asked 2 hours ago









      TomTom

      1053




      1053






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215838%2fredundant-code-that-needs-to-be-refactored%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215838%2fredundant-code-that-needs-to-be-refactored%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          How to make a Squid Proxy server?

          Is this a new Fibonacci Identity?

          Touch on Surface Book