-2

I have got 5 different sources of data(request, lsitCC, listSEDI, listSEDIFees and XMLRoot loaded into respective C# Array list objects). I need to construct a JSON request by combining the data from all of those sources based on certain conditions. I have written below code in C# using NewtonSoft.JSON. The cyclomatic complexity for this LINQ query is coming around 40 which is at a higher side. Could anyone please advice on how the complexity can be reduced. Thanks in advance. I presume the query is pretty user readable, Please let me know if inline comments are required.

    var input = from RequestNode in request
              select new
              {
                  Documents = (from objCC in lsitCC
                               where objCC.ID == RequestNode.ID
                               select new
                               {
                                   Request = (from objSEDI in listSEDI
                                                         where objSEDI.ID == objCC.ID && RequestNode.POSTAL.Count(p => p.PID == objSEDI.PID) > 0
                                                         join Config in RequestNode.POSTAL on objSEDI.PID equals Config.PID
                                                         select new
                                                         {
                                                             ReqItem = (Config.ReqItem == null) ? "" : Config.ReqItem,
                                                             Code = (RequestNode.Code == null) ? "" : RequestNode.Code,
                                                             Camp = (RequestNode.Camp == null) ? "" : RequestNode.Camp,
                                                             CCT = new
                                                             {
                                                                 ID = (objCC.ID == null) ? "" : objCC.ID,
                                                                 Band = (RequestNode.Band == null) ? "" : RequestNode.Band,
                                                                 Context = (RequestNode.Context == null) ? 0 : RequestNode.Context,
                                                                 IsActive = (RequestNode.IsActive == null) ? false : RequestNode.IsActive,
                                                                 MaxLimit = (objCC.MaxLimit == null) ? 0 : objCC.MaxLimit,
                                                                 MinLimit = (objCC.MinLimit == null) ? 0 : objCC.MinLimit
                                                             },
                                                             User = RequestNode.User,
                                                             POSTAL = new
                                                             {
                                                                 PID = (objSEDI.PID == null) ? "" : objSEDI.PID,
                                                                 Type = (Config.Type == null) ? "" : Config.Type,
                                                                 Amount = (Config.Amount == null) ? 0 : Config.Amount,
                                                                 IsValid = (Config.IsValid == null) ? false : Config.IsValid,
                                                                 Code = (Config.Code == null) ? "" : Config.Code,                                                                        
                                                                 Infos = new
                                                                 {
                                                                     Info = (from objRoot in XMLRoot
                                                                             where objRoot.ID == objCC.ID && objRoot.Channel == "Channel1" && objRoot.Group == "GROUP_1" && objRoot.Code == Config.Type.Substring(0, 3) && objRoot.PIDCode == Config.Type.Substring(3, 1)
                                                                             select new
                                                                             {
                                                                                 InfoFrom = (objRoot.InfoFrom == null) ? "" : objRoot.InfoFrom,
                                                                                 Selection = (objRoot.Handling == null) ? "" : objRoot.Selection,
                                                                                 Rate = (objRoot.Rate == null) ? "" : objRoot.Rate                                                                                         
                                                                             })
                                                                 },
                                                                 POSTALFee = from objSEDIFee in listSEDIFees
                                                                              where objSEDIFee.ID == objCC.ID && objSEDIFee.PID == objSEDI.PID
                                                                              select new
                                                                              {
                                                                                  BaseValue = (objSEDIFee.BaseValue == null) ? 0 : objSEDIFee.BaseValue,
                                                                                  UpdatedValue = (objSEDIFee.UpdatedValue == null) ? 0 : objSEDIFee.UpdatedValue,
                                                                                  BaseType = (objSEDIFee.BaseType == null) ? "" : objSEDIFee.BaseType,
                                                                                  UpdatedType = (objSEDIFee.UpdatedType == null) ? 0 : objSEDIFee.UpdatedType
                                                                              },
                                                                 OutputRoot = new
                                                                 {
                                                                     Output = from output in outputroot
                                                                             select new
                                                                             {
                                                                                 Type = 0,
                                                                                 SubType = 0,
                                                                                 OutputReference = 0                                                                                        
                                                                             }
                                                                 }
                                                             },

                                                         })
                               })
              };
    var streamRead = JsonConvert.SerializeObject(input, Newtonsoft.Json.Formatting.Indented);
Mahesh
  • 150
  • 1
  • 9

1 Answers1

1

This seems like simply a case of adding the appropriate amount of translators to your code base. Yes Translators are tedious, but if you feel you have too much logic in one query here, I suggest that could be the way for you to go.

This will mean that you will have to either ditch the anon types, or embrace the dynamic keyword (would that even work?!)

You may also need to look at some sort of build pattern or intermediate state.

On further inspection, it appears that you introduce some global variable halfway down the query e.g. XMLRoot & listSEDIFees. It might be nicer if this was more explicit. You could also cut down on excessive work by pre filtering XMLRoot with the static part of your where clause (objRoot.Channel == "Channel1" && objRoot.Group == "GROUP_1") instead of re-running that each time. Maybe something like

var channel1Group1Info = XMLRoot.Where(objRoot=>objRoot.Channel == "Channel1" && objRoot.Group == "GROUP_1").ToArray();

The rest I would just pick off one piece at a time, reducing the amount of work this query is doing.

Lee Campbell
  • 10,631
  • 1
  • 34
  • 29