문제

There's just GOT TO BE a better way to do this. I am looking at 2000 lines of code that is creating a huge problem with performance and, of course, the "script isn't responding" message.

It's using linq to sql, linq to entities and a little of everything else.

The biggest problem by far I see is that there are dozens and dozens of foreach statements. Each of these looping through (sometimes more than once) a set of objects.

I'm not the best at linq entities methods but I know I've seen examples of .Contains and .Select where I think this would be a good alternative.

I know there has to be a LINQ Method that will do this more efficiently.

Here is a sample of what is happening:

  //RETURNS LIST<LandingPageVendorEvaluation>
  var evaluatedVendors = contactRecords.Where(x => x.VendorId > 0)
   .Select(x => new LandingPageVendorEvaluation()
            {
                ClientVendorId = x.ClientVendorId,
                VendorId = x.VendorId,
                VendorName = x.VendorName,
                Outcome =
                    selectedCount > 0
                        ? (x.VendorIsSelected ? OpportunityOutcomes.Win :
                     OpportunityOutcomes.Loss): OpportunityOutcomes.NoDecision,
                Selected = x.VendorIsSelected,
                IsClient = x.VendorIsClient,
                IsOther = x.VendorIsOther
            }).OrderBy(x => x.VendorName).Distinct().ToList();


           //  NOW a foreach to see if this list of 
           //  LandingPageVendorEvaluation objects is in another
           //  List<LandingPageVendorEvaluation >.  If it isn't there, 
           //  it's added

            foreach (var ev in evaluatedVendors)
            {
                if (profile.EvaluatedVendors.Where(v => v.VendorId == 
                  ev.VendorId).Count() == 0)
                {
                    profile.EvaluatedVendors.Add(ev);
                }
            }

Like I said, this is just an example. Some of these lists contain hundreds of entries.

Any suggestions?

도움이 되었습니까?

해결책

You didn't say what contactRecords and profile exactly is, so it's hard to make sure how to solve the problem in best possible way, but following should do the trick:

var evaluatedVendors = contactRecords.Where(x => x.VendorId > 0)
   .Select(x => new LandingPageVendorEvaluation()
            {
                ClientVendorId = x.ClientVendorId,
                VendorId = x.VendorId,
                VendorName = x.VendorName,
                Outcome =
                    selectedCount > 0
                        ? (x.VendorIsSelected ? OpportunityOutcomes.Win :
                     OpportunityOutcomes.Loss): OpportunityOutcomes.NoDecision,
                Selected = x.VendorIsSelected,
                IsClient = x.VendorIsClient,
                IsOther = x.VendorIsOther
            }).OrderBy(x => x.VendorName).Distinct();

var vendorIds = profile.EvaluatedVendors.Select(v => v.VendorId);

var itemsToAdd = evaluatedVendors.Where(v => !vendorIds.Contains(v.VendorId)).ToList();

profile.EvaluatedVendors.AddRange(itemsToAdd);

However, because you didn't specify what profile is, it may not have AddRange method. If that's the case you can iterate over itemsToAdd instead and call Add instead.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top