Click here to Skip to main content
15,845,681 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I need to convert 2 for each loops which are shown as below to linq -

List<Company> res = new List<Company>();
          List<EmployeeCount> result = new List<EmployeeCount>();
          foreach (string s in indType)
          {
              List<Company> re = _entities.Company.Where(a => Convert.ToString(a.industry_id.ToLower()).Equals(s.ToLower().ToString())).ToList();
              res.AddRange(re);
          }

          foreach (Company r in res)
          {
              List<EmployeeCount> empCount = await _entities.EmployeeCount.Where(a => Convert.ToString(a.Company_ID.ToLower()).Equals(r.Company_id.ToLower())).Select((a => new EmployeeCount() { Company_ID = a.Company_ID, Industry_ID = a.Industry_ID, Company_Name = a.Company_Name, City = a.City, Number_Employees = a.Number_Employees })).ToListAsync();
              result.AddRange(empCount);
          }
          return result.AsQueryable();



I need to optimize these foreach loops using lambda expressions in order to fetch the data fastly. Please help me on this.

What I have tried:

tried like below -

res.ForEach(i => i.company_id).intersect(_entities.EmployeeCount.Select(i => i.company_id).ToList();

its showing it returns List<string> only, I need List<employeecount>. Unable to select the values of EmployeeCount entity.
Posted
Updated 20-Jul-18 5:54am
v2
Comments
F-ES Sitecore 20-Jul-18 7:56am    
Your linq loops will probably be slower than your existing code. Linq is not for performance. If that's your aim then leave your code as it is.

Not entirely clear what you're trying to do, but assuming you're using Entity Framework, something like this should work:
C#
return _entities.EmployeeCount.Where(ec => indType.Contains(ec.Industry_ID));

If the Industry_ID column on the EmployeeCount entity doesn't match the column of the same name on the Company entity, then you'll need a navigation property:
C#
return _entities.EmployeeCount.Where(ec => indType.Contains(ec.Company.Industry_ID));

If the EmployeeCount set doesn't return an instance of your EmployeeCount class, then add a .Select(...) to the end:
C#
return _entities.EmployeeCount
    .Where(ec => indType.Contains(ec.Industry_ID))
    .Select(ec => new EmployeeCount
    {
        Company_ID = ec.Company_ID, 
        Industry_ID = ec.Industry_ID, 
        Company_Name = ec.Company_Name, 
        City = ec.City, 
        Number_Employees = ec.Number_Employees,
    });
 
Share this answer
 
Comments
sri4dotnet 20-Jul-18 11:06am    
yes I am using Entity Framework Core, the above mentioned code was written in a method which has input parameter as string[] indType.
for each string in indType, I am fetching the data from Company table using linq and loading into a List<company>.
Based on the List<company>, again I am fetching the data from database using linq for List<employeecount> based on company_id.
Richard Deeming 20-Jul-18 11:07am    
So try the code I posted - it should be considerably faster.
If you are looking for speed, loops are the way to go.

I would take a look at your data. Does every company have an employee count? If they do then there is not a need for the first loop. All the first loop does is get a list of Company IDs based on Industry ID that you are then using in the second loop which also has Industry ID.

Do you also need to make a new instance of EmployeeCount or can you use the original object? Using the original will save time rather than creating a new instance.

I would do something similar to this if the first loop doesn't matter and you do not need a copy of the object

List<EmployeeCount> result = new List<EmployeeCount>();

foreach (EmployeeCount c in _entities.EmployeeCount)
{
    if (indType.Contains(c.industry_id))
    {
        result.Add(c);
    }
}

return result;
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900