2

I am Using EntityFramework as Dataaccess to View a DropDownList of Countries to my Enduser in an asp.net mvc Webapplication.

It is not a Hard thing to achieve this but i have a little struggle to find a good looking way.

But first of all some Code:

<td>
     @Html.DropDownListFor(x => x.ParentId, repos.GetParents(@Model.ParentId)
</td>

Somewhere deep in the real Code:

class dummy
    {
        public string Text { get; set; }
        public int Value { get; set; }
    }

    private SelectList _parents;
    public SelectList Parents
    {
        get
        {
            if (_parents == null)
            {
                var parents = Entities.Instance.Partners.Select(x => new dummy() { Text = x.Name, Value = x.Id }).OrderBy(x => x.Text).ToList();
                parents.Insert(0, new dummy());

                _parents = new SelectList(parents, "Value", "Text");
            }
            return _parents;
        }
    }

    public SelectList GetParents(int? parentId)
    {
        if (parentId != 0 && parentId.HasValue)
        {
            //setSelected
        }
        return Parents;
    }

As you can see i created a ** dummy class only to copy the Data! Why? Because x.Id.ToString or equivalent Methods dont work in linq to entity...

Still there is something like SqlFunctions.Tostring((double)x.ID) this isnt the perfect solution but good enaught. At least Until i have seen it made the Id 4 to a string like this: "*lotsofspaces*4" and Trimming each value was too much to be considered as a good solution to me.

The most beautiful code solution is this:

new SelectList(Entities.Instance.Partners, "Id", "Name");

Beautiful isnt it? :) NO ITS NOT! Because it selects the whole Data from Partners - not only the ID and Name Column.

So my question: Can you tell me a clean and good looking way to get My Data from EntityFrame in a Dropdown while my valueField is an int valuetype?

Marguth
  • 191
  • 9

3 Answers3

2
new SelectList(Entities.Instance.Partners.Select(o => new { Id = o.Id, Name = o.Name }).ToList(), "Id", "Name");
Pluc
  • 2,909
  • 1
  • 22
  • 36
2

Couple of things:

  1. You do not need to create the dummy class. Simply use Dictionary<int, string>
  2. Do not call GetParents from the view. Do this in the controller's action method and then pass the list into the view
  3. You do not need to insert the empty item into the list. The DropDownList HTML helper has an overload that takes in the text for an empty item to set as the first option. In the code below it will show "Select...", but you can simply provide an empty string.

Some where deep in your code:

public Dictionary<int, string> GetItems(int parentId)
{
    return (from partner in Entities.Instance.Partners
               order by partner.Text
              select partner).ToDictionary(x => x.Id, v => v.Name);

}

Controller:

public ActionMethod MyPage(int parentId)
{
    var myView = new MyViewModel();
    myView.Items = _service.GetItems(parentId);
}

View:

@Html.DropDownList("parentId", new SelectList(Model.Items, "Key", "Value"), "Select...")
Andy T
  • 10,223
  • 5
  • 53
  • 95
  • I like your better. Very clean. – Jay Aug 07 '13 at 15:47
  • cant find that overload in Html.DropDownListFor... PS: your solution is definitly the most elegant way, but i personally prefere the lazy one line way. – Marguth Aug 07 '13 at 15:54
1

You could basically do the same thing your doing, only instead of delaring and using "dumy" you could use an anonymous type:

new SelectList(Entities
    .Instance
    .Partners
    .Select(e => new 
    {
        Id = e.Id,
        Name = e.Name,
    }), "Id", "Name");

Of course your still exposing a SelectList from what could become your "data layer", which is FAR worse than selecting a few extra columns to populate a dropdown list. Remember your time as a developer is much more expensive than a few IO/Cpu cycles. Worry more about the implementation than performance.

Jay
  • 6,224
  • 4
  • 20
  • 23
  • "Remember your time as a developer is much more expensive" Yes we do, exposing them in a request specific lazy loading repository seemed to us as a fast and good way. – Marguth Aug 07 '13 at 16:02