none
Pasar una coleccion anónima a una colecion con un model List<Anonymous> to List <TheModel> RRS feed

  • Pregunta

  • Hola,

    Soy nueva en MVC4 y Linq y estoy teniendo unos problemas de conversión. con el siguiente error:

    "No se puede convertir implícitamente el tipo 'object' en 'System.Collections.Generic.List<TheModell>'. Ya existe una conversión explícita (compruebe si le falta una conversión)."Básicamente lo que intento hacer es desde el controller pasar al view una consulta con que implica varias tablas y estoy utilizando joins, entonces necesito que la colección que me devuelve esa consulta sea una lista del modelo que estoy utilizando.

    desde el Controller realizo la consulta:

                

            dbHutRes hutRes = new dbHutReDataContext();

            public List<HomeViewModel> GetHomeViewModel()
            {
                dynamic ReservationDay = (from c in hutRes.Clients
                                      join r in hutRes.Reservations on c.ID_Client equals r.FK_Client
                                      join ht in hutRes.Hut_Types on r.FK_HutType equals ht.ID_Hut_Type
                                      join tr in hutRes.Time_Reserves on r.FK_TimeReserve equals tr.ID_Time_Reserve
                                      join tc in hutRes.Type_ClientIds on c.FK_TypeClientId equals tc.ID_Type_ClientId
                                      where r.DateR == DateTime.Now
                                      select new
                                      {
                                          r.ID_Reservation,
                                          tc.ClientId,
                                          Number = c.Number_ID,
                                          c.Name,
                                          c.Phone,
                                          time = tr.TimeReserve,
                                          ReservationDate = r.DateR                                      
                                      }).AsQueryable();

                return ReservationDay;  
            }
             public ActionResult Index()
            {
                return View(GetHomeViewModel());
            }

    El view lo tengo de esta forma:

    @model List<HutReservation.ViewModel.HomeViewModel>

    @{
        ViewBag.Title = "Index";
        Layout = "~/Views/Shared/_Layout.Mobile.cshtml";
    }

    <h2>Index</h2>

    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <table>

    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.ID_Reservation)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ClientID)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Number)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Phone)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.time)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReservationDate)
            </td>

    <tr>....etc

    Si alguien me pudiera ayudar estaré muy agradecida :)



    Linda Barros

    miércoles, 5 de marzo de 2014 17:11

Todas las respuestas

  • hola

    el codigo no hace magia, asignar esto

    dynamic ReservationDay

    en esto

    List<HomeViewModel>

    esta claro que no se puede

    podrias usar

     public List<HomeViewModel> GetHomeViewModel()
    {
    	var ReservationDay = (from c in hutRes.Clients
    						  join r in hutRes.Reservations on c.ID_Client equals r.FK_Client
    						  join ht in hutRes.Hut_Types on r.FK_HutType equals ht.ID_Hut_Type
    						  join tr in hutRes.Time_Reserves on r.FK_TimeReserve equals tr.ID_Time_Reserve
    						  join tc in hutRes.Type_ClientIds on c.FK_TypeClientId equals tc.ID_Type_ClientId
    						  where r.DateR == DateTime.Now
    						  select new HomeViewModel()
    						  {
    							  r.ID_Reservation,
    							  tc.ClientId,
    							  Number = c.Number_ID,
    							  c.Name,
    							  c.Phone,
    							  time = tr.TimeReserve,
    							  ReservationDate = r.DateR                                      
    						  }).ToList();
    
    	return ReservationDay;  
    }

    y devolver todo tipado

    o sino usa dynamic en todo

    public List<dynamic> GetHomeViewModel()
    {
    	List<dynamic> ReservationDay = (from c in hutRes.Clients
    						  join r in hutRes.Reservations on c.ID_Client equals r.FK_Client
    						  join ht in hutRes.Hut_Types on r.FK_HutType equals ht.ID_Hut_Type
    						  join tr in hutRes.Time_Reserves on r.FK_TimeReserve equals tr.ID_Time_Reserve
    						  join tc in hutRes.Type_ClientIds on c.FK_TypeClientId equals tc.ID_Type_ClientId
    						  where r.DateR == DateTime.Now
    						  select new 
    						  {
    							  r.ID_Reservation,
    							  tc.ClientId,
    							  Number = c.Number_ID,
    							  c.Name,
    							  c.Phone,
    							  time = tr.TimeReserve,
    							  ReservationDate = r.DateR                                      
    						  }).ToList();
    
    	return ReservationDay;  
    }

    pero todo mezclado no puedes

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    miércoles, 5 de marzo de 2014 17:28
  • Hola,

    Gracias por responder, he realizado el segundo ejemplo y me ha salido el siguiente error al compilar: 

    Error 4 Cannot implicitly convert type 'System.Linq.IQueryable<AnonymousType#1>' to 'System.Collections.Generic.List<dynamic>'. An explicit conversion exists (are you missing a cast?)

    En el primer caso me esta devolviendo el mismo error :(

    Gracias por la ayuda



    LeBarros

    miércoles, 5 de marzo de 2014 17:39
  • recuerda que tienes que usar el ToList() en el linq

    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    miércoles, 5 de marzo de 2014 18:57
  • Ojo con mandarle una List<dynamic> como modelo de una vista que contenga objetos anónimos como los generados por LINQ, pues no podrás acceder a las propiedades de los elementos en la vista.

    Cuando hagas @Html.DisplayFor(modelItem => item.ID_Reservation) te compilará bien (puesto que el tipo de modelo de la vista será IEnumerable<dynamic> pero en ejecución te petará diciendo que Object no tiene ID_Reservation. Lo mismo te ocurrirá con el resto de propiedades.

    El problema es debido, básicamente, a que en .NET los tipos anónimos tienen visibilidad interna, por lo que no son visibles desde otro assembly y en MVC las vistas se ejecutan en OTRO assembly distinto del de los controladores.

    Soluciones hay varias. Te pongo tres:

    1. No usar objetos anónimos de LINQ. Es decir cambiar el select new {... } por select new MyClase {...}. Problema: obligado a definir una clase por cada posible tipo de consulta.
    2. Usar objetos anónimos pero cuando los mandes a la vista, convertir el tipo anónimo en un tipo fijo de .NET. Esto es algo parecido a lo que intentabas hacer tu, con tu código y básicamente adolece del mismo problema que (1).
    3. Usar dynamic y tipos anónimos, pero ANTES de mandarlos a la vista "encapsular" cada tipo anónimo en un ExpandoObject. A la vista seguir usando IEnumerable<dynamic> como tipo de modelo. En mi blog puse hace tiempo como realizar esta aproximación: http://geeks.ms/blogs/etomas/archive/2013/09/12/modelos-de-vista-din-225-micos-en-asp-net-mvc.aspx (léete también el post de pedro hurtado http://geeks.ms/blogs/phurtado/archive/2013/09/16/yo-soy-tu-guard-237-an.aspx)

    Saludos!


    Eduard Tomàs Blog: http://geeks.ms/blogs/etomas -- Twitter: eiximenis

    jueves, 6 de marzo de 2014 12:16
  • bueno al final era algo super simple que me estuve rompiendo la cabeza por mi ignorancia con el lenguaje simplemtente me cree un select new Miclase, en vez de anonimo y taran!!

    select new HomeViewModel 
    {
    // Set class variables here...
    }


    LeBarros

    viernes, 7 de marzo de 2014 14:50
  • simplemtente me cree un select new Miclase, en vez de anonimo y taran

    pero eso siempre se pudo realizar, yo habia pensado que esa clase no queria definirla

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    viernes, 7 de marzo de 2014 16:58