Principales respuestas
MVC + EF + LINQ con inner joins

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!
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.
Si he contestado tu pregunta, por favor marca mi post como respuesta.
...Y si mi post te ha servido, márcalo como útil- Marcado como respuesta Greevard Dem martes, 24 de abril de 2012 19:00
-
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.
- Marcado como respuesta Greevard Dem martes, 24 de abril de 2012 18:51
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.
Si he contestado tu pregunta, por favor marca mi post como respuesta.
...Y si mi post te ha servido, márcalo como útil -
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.
Si he contestado tu pregunta, por favor marca mi post como respuesta.
...Y si mi post te ha servido, márcalo como útil- Marcado como respuesta Greevard Dem martes, 24 de abril de 2012 19:00
-
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
-
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.
- Marcado como respuesta Greevard Dem martes, 24 de abril de 2012 18:51
-
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.
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!
-