none
MVC + EF + LINQ con inner joins RRS feed

  • Pregunta

  • Excelentes dias a todos. tengo una gran duda que me esta carcomiendo la cabeza. 

    yo tengo mi sistema MVC tengo pilotos. y perfiles y la tabla de horas de vuelo. 

    en el modelo EF tengo 3 tablas distintas las cuales consulto en el controller de la siguiente forma 

    var listPiloto = from p in db.Pilotos
                                 join per in db.TblPerfiles
                                 on p.idPerfil equals per.IdPerfil
                                 select new { pilotName=p.Name,nombrePerfil = per.Descripcion };

    el problema es mostrar estos datos en la vista, ya que la vista esta tipada como model.piloto y cuando quiero leer los datos me genera un error del tipo 

    The model item passed into the dictionary is of type 'System.Data.Objects.ObjectQuery`1[<>f__AnonymousType0`2[System.String,System.String]]', but this dictionary requires a model item of type 'MvcAerolineas.Models.Piloto'.

    si le saco el inner join la vista se muestra perfecto, como hago para mostrar datos resultado de linq con inner joins? de que tipo es la vista y como los puedo mostrar?? 

    Desde ya muchísimas Gracias! 

    martes, 24 de abril de 2012 14:12

Respuestas

  • Sería necesario conocer la estructura de MvcAerolineas.Models.Piloto. ¿Tienes un miembro público que se llame nombrePerfil? Si es así, puedes hacer esto:

    var listPiloto = from p in db.Pilotos
                                 join per in db.TblPerfiles
                                 on p.idPerfil equals per.IdPerfil
                                 select new MvcAerolineas.Models.Piloto { pilotName=p.Name,nombrePerfil = per.Descripcion };



    Yo supongo que no tienes un miembro nombrePerfil en MvcAerolineas.Models.Piloto, luego, en la vista de Piloto no puedes mostrar esa información. Tienes que replantearte tu modelo. Por ejemplo, una opción es que Perfil sea un miembro de Piloto y que cada objeto Piloto exponga la propiedad que quieres mostrar (de solo lectura) En ese caso, bastaría con consular el enumerable de pilotos. Otra opción es que crees un Decorator para Piloto (¿por ejemplo, PilotoView?) y bases tu vista en PilotoView en vez de Piloto. El Decorator tendrá dos miembros para guardar el piloto y su perfil y tantos miembros públicos como atributos quieras mostrar.



    logo osoft
    Si he contestado tu pregunta, por favor marca mi post como respuesta.
    ...Y si mi post te ha servido, márcalo como útil smile

    • Marcado como respuesta Greevard Dem martes, 24 de abril de 2012 19:00
    martes, 24 de abril de 2012 15:11
  • Hola,

    puedes usar vistas sin tipo, o puedes usar vistas tipadas, pero sabiendo que vas a pasarle. Lo que no entiendo del primer código es que la vista espera un elemento de tipo Piloto, pero si quitas el join, la consulta te puede devolver una lista por lo que te seguiría fallando. Mi consejo es crearte un objecto a tu medido y ahí rellenes los datos que estimes oportunos. Por ejemplo, te creas esta clase

    public class PilotModel
    {
      public string pilotName { get; set; }
      public string nombrePerfil { get; set; }
    }
    Ahora podrás hacer esto

    var listPiloto = from p in db.Pilotos
                     join per in db.TblPerfiles
                       on p.idPerfil equals per.IdPerfil
                     select new PilotModel { 
                       pilotName = p.Name, 
                       nombrePerfil = per.Descripcion };
    
    return View(listPiloto);
    Y a tu vista le asignas el tipo IEnumerable<PilotModel> o PilotModel dependiendo de si espera uno o varios valores (en caso de ser un único valor podrias añadir SingleOrDefault al final de tu consulta.


    Atentamente, Sergio.

    Blog
    Twitter

    • Marcado como respuesta Greevard Dem martes, 24 de abril de 2012 18:51
    martes, 24 de abril de 2012 18:36

Todas las respuestas

  • Sería necesario conocer la estructura de MvcAerolineas.Models.Piloto. ¿Tienes un miembro público que se llame nombrePerfil? Si es así, puedes hacer esto:

    var listPiloto = from p in db.Pilotos
                                 join per in db.TblPerfiles
                                 on p.idPerfil equals per.IdPerfil
                                 select new MvcAerolineas.Models.Piloto { pilotName=p.Name,nombrePerfil = per.Descripcion };

    Yo supongo que no tienes un miembro nombrePerfil en MvcAerolineas.Models.Piloto, luego, en la vista de Piloto no puedes mostrar esa información. Tienes que replantearte tu modelo. Por ejemplo, una opción es que Perfil sea un miembro de Piloto y que cada objeto Piloto exponga la propiedad que quieres mostrar (de solo lectura) En ese caso, bastaría con consular el enumerable de pilotos. Otra opción es que crees un Decorator para Piloto (¿por ejemplo, PilotoView?) y bases tu vista en PilotoView en vez de Piloto. El Decorator tendrá dos miembros para guardar el piloto y su perfil y tantos miembros públicos como atributos quieras mostrar.


    logo osoft
    Si he contestado tu pregunta, por favor marca mi post como respuesta.
    ...Y si mi post te ha servido, márcalo como útil smile

    martes, 24 de abril de 2012 15:10
  • Sería necesario conocer la estructura de MvcAerolineas.Models.Piloto. ¿Tienes un miembro público que se llame nombrePerfil? Si es así, puedes hacer esto:

    var listPiloto = from p in db.Pilotos
                                 join per in db.TblPerfiles
                                 on p.idPerfil equals per.IdPerfil
                                 select new MvcAerolineas.Models.Piloto { pilotName=p.Name,nombrePerfil = per.Descripcion };



    Yo supongo que no tienes un miembro nombrePerfil en MvcAerolineas.Models.Piloto, luego, en la vista de Piloto no puedes mostrar esa información. Tienes que replantearte tu modelo. Por ejemplo, una opción es que Perfil sea un miembro de Piloto y que cada objeto Piloto exponga la propiedad que quieres mostrar (de solo lectura) En ese caso, bastaría con consular el enumerable de pilotos. Otra opción es que crees un Decorator para Piloto (¿por ejemplo, PilotoView?) y bases tu vista en PilotoView en vez de Piloto. El Decorator tendrá dos miembros para guardar el piloto y su perfil y tantos miembros públicos como atributos quieras mostrar.



    logo osoft
    Si he contestado tu pregunta, por favor marca mi post como respuesta.
    ...Y si mi post te ha servido, márcalo como útil smile

    • Marcado como respuesta Greevard Dem martes, 24 de abril de 2012 19:00
    martes, 24 de abril de 2012 15:11
  • Yvan antes que nada muchas gracias por contestar,  el modelo piloto es el que obtengo de mi EF o sea el modelo que uso es el contexto del EF. 

    en la base de datos hay una tabla pilotos y otra tabla perfiles en el controler . adjunto código 

    public ActionResult Getpilotos()
            {
                GrevonlineEntities db = new GrevonlineEntities();
                var listPiloto = from p in db.Pilotos
                                 join per in db.TblPerfiles
                                 on p.idPerfil equals per.IdPerfil
                                 select new { PilotId = p.PilotId, pilotName=p.Name,nombrePerfil = per.Descripcion };
                return View("Getpilotos",listPiloto);        
            }

    Agrego el modelo que especializa piloto

    namespace MvcAerolineas.Models
    {
        public partial class Piloto
        {
            public string NombrePerfil { get; set; }
            public int CantHoras { get; set; }
            //public string PilotId { get; set; }
            public string pilotName { get; set; }   

        }

    y la view  esta fuertemente tipada!    el problema radica en que tipo de vista debería usar para poder dibujar un objeto que no es del tipo del que hereda la vista.. como haria eso , tengo que crear un partial para hacer eso, no puedo usar VISTAS sin tipo ?  


    • Editado Greevard Dem martes, 24 de abril de 2012 18:33
    • Marcado como respuesta Greevard Dem martes, 24 de abril de 2012 19:00
    • Desmarcado como respuesta Greevard Dem martes, 24 de abril de 2012 19:01
    martes, 24 de abril de 2012 18:15
  • Hola,

    puedes usar vistas sin tipo, o puedes usar vistas tipadas, pero sabiendo que vas a pasarle. Lo que no entiendo del primer código es que la vista espera un elemento de tipo Piloto, pero si quitas el join, la consulta te puede devolver una lista por lo que te seguiría fallando. Mi consejo es crearte un objecto a tu medido y ahí rellenes los datos que estimes oportunos. Por ejemplo, te creas esta clase

    public class PilotModel
    {
      public string pilotName { get; set; }
      public string nombrePerfil { get; set; }
    }
    Ahora podrás hacer esto

    var listPiloto = from p in db.Pilotos
                     join per in db.TblPerfiles
                       on p.idPerfil equals per.IdPerfil
                     select new PilotModel { 
                       pilotName = p.Name, 
                       nombrePerfil = per.Descripcion };
    
    return View(listPiloto);
    Y a tu vista le asignas el tipo IEnumerable<PilotModel> o PilotModel dependiendo de si espera uno o varios valores (en caso de ser un único valor podrias añadir SingleOrDefault al final de tu consulta.


    Atentamente, Sergio.

    Blog
    Twitter

    • Marcado como respuesta Greevard Dem martes, 24 de abril de 2012 18:51
    martes, 24 de abril de 2012 18:36
  • Hola,

    puedes usar vistas sin tipo, o puedes usar vistas tipadas, pero sabiendo que vas a pasarle. Lo que no entiendo del primer código es que la vista espera un elemento de tipo Piloto, pero si quitas el join, la consulta te puede devolver una lista por lo que te seguiría fallando. Mi consejo es crearte un objecto a tu medido y ahí rellenes los datos que estimes oportunos. Por ejemplo, te creas esta clase

    public class PilotModel
    {
      public string pilotName { get; set; }
      public string nombrePerfil { get; set; }
    }
    Ahora podrás hacer esto

    var listPiloto = from p in db.Pilotos
                     join per in db.TblPerfiles
                       on p.idPerfil equals per.IdPerfil
                     select new PilotModel { 
                       pilotName = p.Name, 
                       nombrePerfil = per.Descripcion };
    
    return View(listPiloto);
    Y a tu vista le asignas el tipo IEnumerable<PilotModel> o PilotModel dependiendo de si espera uno o varios valores (en caso de ser un único valor podrias añadir SingleOrDefault al final de tu consulta.


    Atentamente, Sergio.

    Blog
    Twitter

    Excelente es loq ue necesitaba, porque no entendia como jugar con los LINQ y las consultas, es mas estaba buscando la forma de poder traer informacion desde un Store procedure! Muchas GRACIAS! 

    martes, 24 de abril de 2012 18:52
  • y como mostrar en la vista estos datos ?
    domingo, 2 de julio de 2017 16:14