0

Say you have the following scenario:

  • Table: Country; Columns: CountryID, CountryName
  • Table: State; Columns: StateID, StateName, CountryID (foreign key)
  • Table: Locality; Columns: LocalityID, LocalityName, StateID (foreign key)

In MVC, it is nice that the auto-generated LINQ-TO-SQL classes map association relationships in the code so you can call the linked foreign entity, e.g. in my view I can have:

<% foreach (var locality in Model.Localities) { %>

    <tr>
        <td>
            <%: locality.LocalityName %>
        </td>
        <td>
            <%: locality.State.StateName %>
        </td>
        <td>
            <%: locality.State.Country.CountryName %>
        </td>
    </tr>

<% } %>

This succesfully renders when I browse to the index action.

However, I am having problems with the Edit action. Here's the code:

        <strong>Locality Name</strong>
        <div class="editor-field">
            <%: Html.TextBox("LocalityName", Model.Locality.LocalityName) %>
            <%: Html.ValidationMessage("LocalityName")%>
        </div>

        <strong>Country</strong>
        <div class="editor-field">
            <%= Html.DropDownList("CountryID", Model.CountriesDDL, "-- select --") %>
        </div>

        <strong>State</strong>
        <div class="editor-field">
            <%= Html.DropDownList("StateID", Model.StatesDDL, "-- select--") %>
            <%: Html.ValidationMessage("StateID")%>
        </div>

At first I was getting a validation error next to the selectlist of states (for the StateID) which said, e.g., "8 is not a valid value." So it isn't updating.

I understand, from reading a number of posts (such as this one), that there is a database-related problem updating the relationship by setting the ID, and that the solution appears to be to set the ENTITY instead. (Incidentally, contrary advice is also dispensed here). Following this advice, I have been looking at overloads of Html.DropDownList() to set the "value" of the list item to the object itself, whilst setting the "text" property to the Object.Name - I haven't solved this yet. But as this undertaking is becoming more time-consuming, I would very much appreciate some expert advice.

Therefore, my questions are: will this actually work if I get it going? And is it possible to get the SelectList to work this way (and any suggestions as to how)?

Thanks for your time,

Tim.

Community
  • 1
  • 1
Hanshan
  • 3,656
  • 5
  • 29
  • 36

2 Answers2

0

In general it is also not a good idea to pass your domain model to your View (except perhaps in list Views).

Better using a (proxy) ViewModel which is a flattened version of your domain model. It is a bit more work, but works like a charm.

Gideon
  • 18,251
  • 5
  • 45
  • 64
  • Do you mean, e.g., instead of calling "Locality.State.Country.CountryName" define in the LocalityViewModel class a string "CountryName" which returns "Locality.State.Country.CountryName", which is then passed to the view as "Model.CountryName"? – Hanshan Nov 28 '10 at 23:57
  • In your case I would have a viewmodel - a simple class - with only CountryID, StateID and LocalityName, and some "helper" IEnumerables (Countries, States). Normally I add two methods to my viewmodels, 1) update which receives your entity class and fills it with data from the viewmodel. And 2) Init, which receives an entity class, and a repository, and which fills the ViewModel from the entity, and fills the helper list from the repository. This way your controller only checks if the ModelState is valid, and unloads all the dirty work to your viewmodel. – Gideon Nov 29 '10 at 07:38
  • You've given the info I needed to solve the problem. That's brilliant - thanks a lot, mate! Have implemented your pattern, with calling to viewmodel class to do the work of updating the related entity. Works a treat! – Hanshan Nov 30 '10 at 03:30
0

Try playing with this code to populate your list, it works for me., here I am working with product.

           <%:Html.DropDownListFor(m => m.Id, new SelectList(Model.Categories, "Id", "Name", Model.Product.CategoryId, "-Select-")%>

Use DTOs for showing list like stuff. Entities can be used for Create,Update,Delete

indiPy
  • 7,844
  • 3
  • 28
  • 39
  • Thanks, mate - have been playing around with this - the errors have disappeared but the update has not been occuring. I've played around setting the lamba to m => m.relatedEntity (rather than m => m.relatedEntityID). This in the hope the UpdateModel() method does the work rather than me having to, e.g., specify on the controller object.relatedEntity = viewDataObject. Is that what you mean by "use entities for create, update, delete"? – Hanshan Nov 28 '10 at 23:49