0
epublic ActionResult ExistingPolicies()
    {
        if (Session["UserId"]==null)
        {
            return RedirectToAction("Login");
        }
        using(PMSDBContext dbo=new PMSDBContext())
        {
            List<Policy> viewpolicy = new List<Policy>();
            var userid = Session["UserId"];
            List<AddPolicy> policy= dbo.AddPolicies.Where(c => c.MobileNumber == 
            (string)userid).ToList();
            foreach(AddPolicy p in policy)
            {
                viewpolicy=dbo.Policies.Where(c => c.PolicyId ==p.PolicyId).ToList(); 
            }
            Session["Count"] = policy.Count;
            return View(viewpolicy);
        }
        
    }

Here the policy list clearly has 2 items.But when I iterate through foreach,the viewpolicy list only takes the last item as its value.If break is used,it takes only the first item.How to store both items in viewpolicy list??

Regards Surya.

  • 1
    This will currently run N+1 queries. You should consider doing a single query with a join on the two tables instead: https://stackoverflow.com/q/11204367/5803406 – devNull Sep 07 '20 at 15:24

3 Answers3

1

You can iterate through policies and add them by one to list with Add, but I would say that often (not always, though) better option would be to just retrieve the whole list from DB in one query. Without knowing your entities you can do at least something like that:

List<AddPolicy> policy = ...
viewpolicy = dbo.Policies
    .Where(c => policy.Select(p => p.PolicyId).Contains(c.PolicyId))
    .ToList();  

But if you have correctly set up entities relations, you should be able to do something like this:

var viewpolicy = dbo.AddPolicies
    .Where(c => c.MobileNumber == (string)userid)
    .Select(p => p.Policy) //guessing name here, also can be .SelectMany(p => p.Policy)
    .ToList(); 
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
0

Of course; instead of adding to the list, you replace it with a whole new one on each pass of the loop:

viewpolicy=dbo.Policies.Where(c => c.PolicyId ==p.PolicyId).ToList()

This code above will search all the policies for the policy with that ID, turn it into a new List and assign to the viewpolicy variable. You never actually add anything to a list with this way, you just make new lists all the time and overwrite the old one with the latest list

Perhaps you need something like this:

 viewpolicy.Add(dbo.Policies.Single(c => c.PolicyId ==p.PolicyId));

This has a list, finds one policy by its ID number (for which there should be only one policy, right? It's an ID so I figured it's unique..) and adds it to the list

You could use a Where and skip the loop entirely if you wanted:

viewpolicy=dbo.Policies.Where(c => policy.Any(p => c.PolicyId == p.PolicyId)).ToList();

Do not do this in a loop, it doesn't need it. It works by asking LINQ to do the looping for you. It should be converted to an IN query and run by the DB, so generally more performant than dragging the policies out one by one (via id). If the ORM didn't understand how to make it into SQL you can simplify things for it by extracting the ids to an int collection:

viewpolicy=dbo.Policies.Where(c => policy.Select(p => p.PolicyId).Any(id => c.PolicyId == id)).ToList();

Final point, I recommend you name your "collections of things" with a plural. You have a List<Policy> viewpolicy - this is a list that contains multiple policies so really we should call it viewPolicies. Same for the list of AddPolicy. It makes code read more nicely if things that are collections/lists/arrays are named in the plural

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
-1

Something like:

            viewpolicy.AddRange(dbo.Policies.Where(c => c.PolicyId ==p.PolicyId)); 
Milney
  • 6,253
  • 2
  • 19
  • 33