LINQ to Entities only supports casting Entity Data Model primitive types?

24,193

Solution 1

How about this:

ViewBag.category = 
    from c in new IntraEntities().CategoryItems.ToList()
    select new SelectListItem 
    {
        Text = c.Name, 
        Value = c.ID.ToString() 
    };

and how about using strongly typed view models instead of some weakly typed crap of a ViewBag (it's the way I call it)?

Like this:

public class CategoryViewModel
{
    public string CategoryId { get; set; }
    public IEnumerable<SelectListItem> Categories { get; set; }
}

then:

public ActionResult Foo()
{
    var model = new CategoryViewModel
    {
        Categories = 
            from c in new IntraEntities().CategoryItems.ToList()
            select new SelectListItem 
            {
                Text = c.Name, 
                Value = c.ID.ToString() 
            }
    };
    return View(model);
}

and finally in your strongly typed view:

@model CategoryViewModel
@using (Html.BeginForm())
{
    @Html.DropDownListFor(x => x.CategoryId, Model.Categories)
    <button type="submit">OK</button>
}

Much better, don't you think?

Solution 2

You can cast your query to an .AsEnumerable() prior to the conversion to force it to use Linq to Objects for the casting but it is better to use the SQL compatible functions available in System.Data.Objects.SqlClient.SqlFunctions like so:

(from c in new IntraEntities().CategoryItems
select new SelectListItem() { 
    Text = c.Name, 
    Value = SqlFunctions.StringConvert((double)c.ID).TrimStart() 
})
Share:
24,193
Ber53rker
Author by

Ber53rker

Updated on July 09, 2020

Comments

  • Ber53rker
    Ber53rker almost 4 years

    I'm trying to populate a dropdown in my view. Any help is greatly appreciated. Thanks.

    Error:

    Unable to cast the type 'System.Int32' to type 'System.Object'.

    LINQ to Entities only supports casting Entity Data Model primitive types.

    Controller:

    ViewBag.category = (from c in new IntraEntities().CategoryItems
                       select new SelectListItem() {Text=c.Name, Value=""+c.ID }).ToList<SelectListItem>();
    

    View:

    Category:<br />@Html.DropDownList("category", (List<SelectListItem>)ViewBag.category)
    
  • Ber53rker
    Ber53rker over 12 years
    Didn't work, but thanks. "LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression."
  • danludwig
    danludwig over 12 years
    Sorry, Darin is once again correct -- you need to invoke .ToList() to execute the query. Then, LINQ to Objects will recognize the .ToString() call.
  • Darin Dimitrov
    Darin Dimitrov over 12 years
    @olivehour, no, I don't need more reputation. I just want to see people stop using this crap of ViewBag and start using view models in their ASP.NET MVC applications.
  • danludwig
    danludwig over 12 years
    +1 again. I have devs in Bangalore that are doing this. I am going to give them a link to this page to show them how viewmodels should model selectlists.
  • Darin Dimitrov
    Darin Dimitrov over 12 years
    @olivehour, no, don't give them link to that page. I mean the example in this web page is far from anything that you should do in a real application. I mean in this example the OP is hardcoding a LINQ-to-Entities or whatever you call it DAL directly in the controller without using an abstraction and rendering this code completely impossible to unit test in isolation. You should absolutely never have your controller strongly tied to a specific data access technology such as EF or whatever. You should weaken the coupling between the different layers of your application by using abstractions.
  • danludwig
    danludwig over 12 years
    I am going to direct them to your answer, and only to show them how to get their select lists should be on the viewmodel, not in the viewbag. We already have a repository abstraction over EF for the controller, but right now, they are putting it in ViewBag instead of on the ViewModel.
  • Sergio
    Sergio almost 10 years
    This is a more acceptable answer to me. The accepted answer just calls a ToList() on the collection, which is probably not required. Then it goes off track and lectures about the use of viewmodel classes.