none
Implementar una consulta en MVC y LinQ como modelo. RRS feed

  • Pregunta

  • Hola...

    Al crear un controlador, el por de fecto me crea los controles para manipular el modelo...osea create,delete,details,edit....

    y yo quiero hacer una consulta!! por ejemplo seleccionar todos los registros con nombre Maria....manipulando un modelo LinQ, para mostrarlos en una vista....

    utilizo:

    SQL Server 2008, VS2008-spk1, MVC2

    martes, 7 de septiembre de 2010 8:40

Respuestas

  • Hola, Donoban.

    Estás indicando dónde está el error, no cuál es... Pero bueno, a la vista de la línea que genera el casque, es probable que algo más arriba aparezca una descripción como:

    • Mensaje de error del compilador: CS0246: No se puede encontrar el tipo o el nombre de espacio de nombres 'mv' (¿falta una directiva using o una referencia de ensamblado?)

    Si es así, se debe a que en es necesario incluir la referencia completa hacia la clase con la que estás tipando la vista, namespaces incluidos. Así, si por ejemplo tu clase "mv" (¡por favor, pásala a mayúsculas!) está definida en el espacio de nombres Algo.Models, las directivas de tu vista deberían ser algo así como:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Algo.Models.mv>>" %>
     

    Otra posibilidad, que evitar hacer esto en cada vista, es añadir el espacio de nombres Algo.Models a la sección <namespaces> del Web.config.

    Saludos & suerte!


    José M. Aguilar
    Variable not found
    • Marcado como respuesta Donoban domingo, 12 de septiembre de 2010 1:25
    miércoles, 8 de septiembre de 2010 19:37
  • Cuando dices que "no te reconoce nombre y apellido" a que te refieres? Que error te da?

    De momento sin más info me lanzo al ruedo! :D

    La clase que contiene (Id, nombre y apellido) se llama "acceso"? No debería llamarse "mv"?? Lo digo pq la vista la declaras como IEnumerable<foro.Models.acceso> y no se yo si deberías declararla de IEnumerable<mv> (donde pongo mv debe ponerse el nombre completo con todos los namespaces de la clase que contiene Id, nombre y apellido.

    Si no tienes claro el nombre de esta clase, mete un breakpoint en el controlador, justo antes de llamar a la vista y mira el tipo de ql (será una List<xxx> y esta xxx es la que nos interesa).

    Por otra parte, estás usando VS2008 o VS2010?

    Si usas VS2008 reemplaza

    <%: persona.nombre %> y <%: persona.apellido %> por

    <%= Html.Encode(persona.nombre) %> y <%= Html.Encode(persona.apellido) %>

    Ya nos contarás...


    Eduard Tomàs Blog: http://geeks.ms/blogs/etomas -- Twitter: eiximenis
    • Marcado como respuesta Donoban jueves, 9 de septiembre de 2010 22:10
    miércoles, 8 de septiembre de 2010 6:15

Todas las respuestas

  • Donoban, hay varias maneras de hacer esto, pero todas se reducen a una acción en el controlador que te devuelve los datos (lo que llamamos un ViewModel) a la vista. Cómo el controlador obtiene los datos depende de tu arquitectura: pero usualmente decimos que el controlador accede al Modelo y le pide esos datos. De nuevo, dependiendo de tu arquitectura el Modelo será una cosa u otra.

    Resumiendo pues, los pasos básicos son:

    1. El controlador en la acción pide los datos al Modelo
    2. Con los datos del Modelo construye un ViewModel (datos concretos que necesita la vista) y pasa dichos datos a la vista.

    Puedes tener una arquitectura simple donde tu Modelo sea un modelo de EF o Linq2Sql y que el controlador lance sentencias linq directamente contra dicho modelo y pase los resultados hacia la vista (en este caso Modelo y ViewModel se confunden). Pero puedes tener arquitecturas más complejas donde el Modelo sea un conjunto de clases (p.ej siguiendo el patrón Repository) que te devuelvan entidades (a partir de consultas contra EF o Linq2Sql) y que el controlador transforme dichas entidades en otros objetos que entienda la vista. En esta arquitectura Modelo, ViewModel y modelo de EF/Linq2Sql están totalmente separados... Todo depende.

    Veamos un ejemplo de la arquitectura más simple, que quizá sea más fácil de entender. Imagina una acción del controlador llamada "List" que devuelva lo que pides: los registros con nombre maría. Dices que usas un modelo Linq... voy a suponer que es Linq2Sql, aunque con EF viene a ser parecido...

    Tendríamos un controlador (p. ej. ClientesController) con una acción List:

    public ActionResult List(string id)
    {
      EntitiesDataContext edc = new EntitiesDataContext();
      var q = from c in edc.Clientes
       where id.Equals(c.NOMBRE)
       select c;
      var ql = q.ToList();
      edc.Dispose();
      return View(ql);
    }
    

    Fíjate lo que hace la acción:

    1. Se connecta a la BBDD (EntitiesDataContext son las clases que Linq2Sql genera de mi BBDD). En mi caso la BBDD tiene una sola tabla (Clientes) con 3 campos (ID, NOMBRE, APELLIDO)
    2. Selecciona todos los clientes cuyo nombre sea igual al id pasado
    3. Copia todos los registros obtenidos a una lista (.ToList())
    4. Se desconnecta de la BBDD
    5. Pasa dicha información a la vista

    En este caso mi Modelo son las clases generadas por Linq2Sql (EntitiesDataContext y todo lo que cuelga de él) y mi ViewModel (lo que mando a la vista) es una lista (IEnumerable) de objetos de la clase Cliente.

    Ahora debo crear una vista. Si uso Vs2008 debo crear una vista tipada cuyo tipo sea IEnumerable<Cliente>. Si uso Vs2010 puedo crear un vista dinámica. A mi personalmente me gusta crear vistas tipadas incluso con vs2010... aunque en este ejemplo haya optado por una vista dinámica:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    	List
    </asp:Content>
    <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
      <h2>List</h2>
      <ul>
      <% foreach (var cliente in Model)
        { %>
         <li><%: cliente.NOMBRE %>&nbsp;<%: cliente.APELLIDO %></li> 
      <% } %>
      </ul>
    </asp:Content>
    

    En este caso la vista se limita a iterar sobre el ViewModel que recibe (recuerda que es un IEnumerable) y para cada elemento, generar un tag <li> con el nombre y el apellido.

    Y listos! Si navegas a /Clientes/List/Maria la vista mostrará todos los clientes cuyo nombre es Maria.

    Por lo tanto, lo que queda claro es que:

    1. El Modelo contiene y accede a los datos
    2. El controlador interactúa con el Modelo para pedir datos y encapsularlos en un ViewModel que es mandado a la vista
    3. La vista accede al ViewModel (a través de su propiedad Model) y muestra los datos.

    Un saludo!

     


    Eduard Tomàs Blog: http://geeks.ms/blogs/etomas -- Twitter: eiximenis
    martes, 7 de septiembre de 2010 9:50
  • Hola!!

    Tengo una consulta o mas bien un problema; bueno voy a describir mi proyecto!!

    Esta es la base de datos...

    ---------

    use master
    
    go
    
    create database foro
    
    go
    
    use foro
    
    go
    
    create table mv(id int identity primary key not null,nombre varchar(10) not null, apellido varchar(10) not null)
    
    go
    
    
    

    -------

    El controlador  para consultar seria "personaController.cs"

    public ActionResult Browse(string id)
    
    {
    
    accesoDataContext acc = new accesoDataContext();//nueva instancia de LinQ2SQL del modelo "acceso"
    
    var q = from c in acc.mvs where id.Equals(c.nombre) select c;
    
    var ql = q.ToList();
    
    acc.Dispose();
    
    return View(ql);
    
    }
    
    
    

    ------

    Esta es la vista que la cree de tipo  "IEnumerable<foro.Models.acceso>"

    Y el error esta aquí... o no sé que será el problema...

    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<foro.Models.acceso>>" %>
    
    <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    
    Browse
    
    </asp:Content>
    
    <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    
    <h2>Browse</h2>
    
    <ul>
    
    <% foreach (var persona in Model)
    
    { %>
    
    <li><%: persona.nombre %>&nbsp;<%: persona.apellido %></li> //aqui no me reconoce nombre ni apellido///
    
    <% } %>
    
    </ul>
    
    </asp:Content>
    
    
    

     

    A la vista yo le agregué la parte de las etiquetas<ul></ul>...porque no salío...

    Que estoy haciendo mal o que debo de hacer...

    Gracias de antemano!!

     

    • Editado Donoban miércoles, 8 de septiembre de 2010 2:35 planteo
    miércoles, 8 de septiembre de 2010 2:34
  • Cuando dices que "no te reconoce nombre y apellido" a que te refieres? Que error te da?

    De momento sin más info me lanzo al ruedo! :D

    La clase que contiene (Id, nombre y apellido) se llama "acceso"? No debería llamarse "mv"?? Lo digo pq la vista la declaras como IEnumerable<foro.Models.acceso> y no se yo si deberías declararla de IEnumerable<mv> (donde pongo mv debe ponerse el nombre completo con todos los namespaces de la clase que contiene Id, nombre y apellido.

    Si no tienes claro el nombre de esta clase, mete un breakpoint en el controlador, justo antes de llamar a la vista y mira el tipo de ql (será una List<xxx> y esta xxx es la que nos interesa).

    Por otra parte, estás usando VS2008 o VS2010?

    Si usas VS2008 reemplaza

    <%: persona.nombre %> y <%: persona.apellido %> por

    <%= Html.Encode(persona.nombre) %> y <%= Html.Encode(persona.apellido) %>

    Ya nos contarás...


    Eduard Tomàs Blog: http://geeks.ms/blogs/etomas -- Twitter: eiximenis
    • Marcado como respuesta Donoban jueves, 9 de septiembre de 2010 22:10
    miércoles, 8 de septiembre de 2010 6:15
  • Hola!! ET.

    muchas gracias por tu ayuda!!

    Cuando escribi que " no me reconoce nombre ni apellido" era que me los subrayaba en rojo!!...

    utilizo:

    SQL Server 2008, VS2008-spk1, MVC2

    ya hice todos esos cambios:

    tiene razon es...  IEnumerable<mv>   el  breakpoint me devolvio mv

    hice el camibio en la vista:

    <

     

    li><%= Html.Encode(persona.nombre) %> y <%= Html.Encode(persona.apellido) %></li>

    -----

    ahora lo ejecuto y:

    http://localhost:1238/persona/Browse/ana

    todo bien excelente con el breakpoint me dise que tiene 3 registros en la lista, de hecho asi es por que consulte por "ana", y en realidad existen 3 "ana"

    pero en el navegador me genera un error:

     
    Línea 146: 
    Línea 147: [System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()]
    Línea 148: public class views_persona_browse_aspx : System.Web.Mvc.ViewPage<IEnumerable<mv>>, System.Web.SessionState.IRequiresSessionState, System.Web.IHttpHandler {
    Línea 149:  
    Línea 150:  private static bool @__initialized;

    y ahora que estoy haciendo mal!!

    Gracias!!

     

     

     

    • Editado Donoban miércoles, 8 de septiembre de 2010 14:44 planteo
    miércoles, 8 de septiembre de 2010 14:42
  • Hola, Donoban.

    Estás indicando dónde está el error, no cuál es... Pero bueno, a la vista de la línea que genera el casque, es probable que algo más arriba aparezca una descripción como:

    • Mensaje de error del compilador: CS0246: No se puede encontrar el tipo o el nombre de espacio de nombres 'mv' (¿falta una directiva using o una referencia de ensamblado?)

    Si es así, se debe a que en es necesario incluir la referencia completa hacia la clase con la que estás tipando la vista, namespaces incluidos. Así, si por ejemplo tu clase "mv" (¡por favor, pásala a mayúsculas!) está definida en el espacio de nombres Algo.Models, las directivas de tu vista deberían ser algo así como:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Algo.Models.mv>>" %>
     

    Otra posibilidad, que evitar hacer esto en cada vista, es añadir el espacio de nombres Algo.Models a la sección <namespaces> del Web.config.

    Saludos & suerte!


    José M. Aguilar
    Variable not found
    • Marcado como respuesta Donoban domingo, 12 de septiembre de 2010 1:25
    miércoles, 8 de septiembre de 2010 19:37
  • Hola!!

    De hecho asi era José M.A  lo que paso fue que obvie lo que escribio Eduard T. y entonces ala hora de crear la vista le puse:

    IEnumerable<mv>

    y lo que habia que poner era:

    IEnumerable<foro.Models.mv>

    y asi me finciono!!

    Muchas gracias a los dos por su ayuda...

    jueves, 9 de septiembre de 2010 22:10