views:

93

answers:

3

Hello,

I'm passing 3 sets of data through to a view in a viewmodel and have a problem relating one of them to the other two in my foreach coding:

My DB tables are: "ServiceGroups" is parent to "Services" "Services" is related through a joining table (using a 2 composite Primary Key) to the aspnet_users table (I call "Users")

I pulled this into an EF model called GWServices.edmx

so now I have 3 entities related like so: ServiceGroup (parent to) Service Service (many to many with) User

Then I created a controller and a viewmodel like this:

{

    public class ServicesViewModel
    {
        public ServicesViewModel(List<ServiceGroup> servicegroups, List<Service> services, List<User> aspnetusers)
        {
            this.ServiceGroups = servicegroups;
            this.Service = services;
            this.AspnetUsers = aspnetusers;

        }

        public List<ServiceGroup> ServiceGroups { get; set; }
        public List<Service> Service { get; set; }
        public List<User> AspnetUsers { get; set; }

    }


    public class ClientServicesController : Controller
    {

        public ActionResult Index()
        {
            GWEntities _db = new GWEntities();

            var servicegroups = _db.ServiceGroupSet.ToList();
            var services = _db.ServiceSet.ToList();
            var aspnetusers = _db.UserSet.ToList();

            return View(new ServicesViewModel(servicegroups, services, aspnetusers));
        }

    }
}

Next I created the view with 3 foreach loops to:

  1. Get and present as a UL, a list of all service groups in the database (which worked)
  2. Populate a table under each Servicegroup filling down some Service data for each Service within that given group (which also work)
  3. Test whether the user is associated with this particular Service, if so show only the red cross icon, otherwise show the green "select me" icon. (this doesn't populate any users)

So the code looks like this:

<% foreach (var servgroup in Model.ServiceGroups) { %> 
<ul> <%= servgroup.ServiceGroupName%> </ul>
<table>
     <% foreach (var serv in servgroup.Service)
        { %>
     <tr>
     <td class="td1">
     <%= serv.ServiceDescription%>
     </td>
     <td class="td2">
     <% = Html.Encode(String.Format("{0:f}",serv.MonthlyPrice)) %> 
        </td>
        <td class="td3"> 
           <%foreach (var user in serv.User) {%>
              <%if (user.UserName == User.Identity.Name)
                { %>
            <img src="/Content/LightRedCross_2.png" alt="" height="15px" width="15px"/>
                    <% }
                else
                {%>
            <img src="/Content/LightGreenAdd_2.png" alt="" height="15px" width="15px"/>           
              <%} %>
           <%} %>
        </td>
        </tr>
   <% } %> 
    </table> 
<% } %>

Can anyone tell me why foreach(var user in serv.user) does not recognise that "Customer1" (the currently logged in user) has 6 services ordered (as it is in the joining table)?

Thanks!

Paul

A: 

What's kind of authentication do you use in web.config?

Roy
I'm using Forms: <authentication mode="Forms"> <forms loginUrl="~/Account/LogOn" timeout="2880" /></authentication>
Paul Connolly
A: 

For starters, username comparisons are generally case-insensitive. So this:

          <%if (user.UserName == User.Identity.Name)

...should be:

          <%if (user.UserName.Equals(User.Identity.Name, StringComparison.OrdinalIgnoreCase))

You also have a bug where you don't dispose your entity context. You should override Controller.Dispose and dispose it there. This allows the view to render before the context is disposed.

Craig Stuntz
Thanks for the help on that bit, I have dropped it into the code in readiness for when I figure out how to pull the dataset through from the User table.
Paul Connolly
+1  A: 

Looking at your code I think this could be resolved by loading the child tables of ServiceGroups.

It is likely that the Services & User reference was not loaded in the original Entity Framework query. Therefore, as you are trying to iterate through the children in the foreach loop, it does not see a collection, it just sees null.

You should try altering your retrieval statements:

_db.ServiceGroupSet.ToList()

to

_db.ServiceGroupSet.Include("ServiceSet").Include("UserSet").ToList()

If this doesn't fix your issue, I would put a break point on the below line of code and traverse the List to see if it has the data you expect.

this.ServiceGroups = servicegroups; 
YeahStu
Thanks so much Mr Yeah!Your steer on the .Include("") saved the day.I tailored your example above to the many-to-many relationship and it worked:i.e. var services = _db.ServiceSet.Include("User").ToList();var aspnetusers = _db.UserSet.Include("Service").ToList(); Thanks againPaul
Paul Connolly