none
Consulta Con Linq y entity framework RRS feed

  • Pregunta

  • Buenas tardes a todos. estoy trabajando con Sql server y Entity Framework ahora, tengo una consutal en Sql server, la cual funciona como veran.

    ahora intento hacer la misma consulta que me muestre los mismo campos con Linq. pero me muestran todos los campos, claro yo puedo ocultar en el DatagridView los campos que no quiero mostrar pero.

    pregunto habra la forma de hacer que solo se muestren los campos que quiero mostrar como la consulta SQL SERVER

    select p.Codigo,p.Descripcion, p.PrecioVenta,p.Stock,u.NombreCorto, C.Descripcion from tblProducto p 
    															inner join tblUnidad u on p.IdUnidadMedida = u.Id inner join tblCategoria C on p.IdCategoria = C.Id

    me muestra estos campos

    ahora en C# y Linq tengo este método

    public static List<tblProducto> Lista()
            {
                using (GourmetEntities db = new GourmetEntities())
                {
                    var Listproducs = (from lt in db.tblProductoes
                                       join id in db.tblUnidads on lt.IdUnidadMedida equals id.Id
                                       select lt).ToList();
                    return Listproducs;
                }
            }

    pero me muestra todos los campos, y no quiero que me muestre todos los campos, por ejemplo los IdCategoria e Idunidad.

    tengo también este otro método pero igual muestra todos los campos.

    public static List<Producto> GetProductos()
            {
          
    
                using (GourmetEntities db = new GourmetEntities())
                {
                    var Listproducs = (from fila in db.tblProductoes
                                       join Id in db.tblUnidads on fila.IdUnidadMedida equals Id.Id
                                       select new Producto
                                       {
                                           Id = fila.Id,
                                           Codigo = fila.Codigo,
                                           Descripcion = fila.Descripcion,
                                           PrecioVenta = fila.PrecioVenta,
                                           NombreCortoMedida = fila.tblUnidad.NombreCorto
                                       }).ToList();
                                       
                                      
                    return Listproducs;
                }
    
            }
    

    Por favor esto es Con Entity Framework y Linq. 

    agradezco la ayuda.

    Roberto

    lunes, 23 de marzo de 2020 19:13

Respuestas

  • Ah, vale, ya está claro lo que está sucediendo.

    Cuando devuelves un new Producto y solo inicializas algunas columnas, el objeto "Producto" que devuelves siempre contiene una definición para todas las columnas, lo que pasa es que si no las inicializas en el "new" se quedan con su valor predeterminado (cero si son numéricas, cadena vacía si son strings). Si ese objeto lo tomas y lo asignas al datasource de un grid, entonces el grid lo que hace es pintar en pantalla una columna por cada campo público que exista en el objeto devuelto. No tiene ninguna forma de distinguir si ese campo tiene un cero porque realmente vale cero o porque no has devuelto nada en él desde tu subrutina de acceso a datos.

    Si quieres asignarle al Grid un objeto en el que existen muchas columnas (con independencia de que los valores de dichas columnas hayan sido o no inicializados desde la base de datos) pero solo quieres que el grid muestre algunas de ellas, entonces tienes que ir a las propiedades del Grid y poner false en el "AutoGenerateColumns" y en su lugar acudir a la propiedad Columns y definir cuáles son las que quieres mostrar.

    O, alternativamente, lo que puedes hacer es dejar a true el AutoGenerateColumns y entonces proporcionerle en el DataSource un objeto que solo defina las columnas que quieras mostrar (énfasis en "defina", da igual que las hayas inicializado o no las hayas inicializado con valores tomados desde la base de datos). Ese objeto puede ser anónimo si lo deseas (como hiciste en tu segundo ejemplo), o puede ser una clase definida expresamente con solo los campos que quieres mostrar.

    martes, 24 de marzo de 2020 7:26
    Moderador

Todas las respuestas

  • El segundo método está bien. Con esa variante solo se recuperan los campos que tienes dentro del "select new Producto{...}". El procedimiento no devuelve ningún otro campo aparte de esos. Por lo tanto, es imposible que te los muestre. Si te los está mostrando, quiere decir que no se está ejecutando ese método, sino que tienes alguna llamada en algún otro sitio que los está recuperando por otra vía diferente.
    lunes, 23 de marzo de 2020 22:27
    Moderador
  • De antemano gracias Alberto Poblacion

    hice estas dos llamadas a dos DatagriView

     dataGridView2.DataSource = Producto.GetProductos();
    
    


    y me da estas imagen

    muestra como ve en la imagen y en la primer columna esta bien

    pero me sigue mostrando las demas columnas

    ahora hice esto que Sí funciona pero pregunto sera correcto hice un object como se ve

    public static object Lista()
            {
                using (GourmetEntities db = new GourmetEntities())
                {
                    var Listproducs = (from lt in db.tblProductoes
                                       join id in db.tblUnidads on lt.IdUnidadMedida equals id.Id join IdCat in db.tblCategorias on lt.IdCategoria equals IdCat.Id
                                       select new
                                       {
                                           Codigo = lt.Codigo,
                                           Descripcion = lt.Descripcion,
                                           PrecioVenta = lt.PrecioVenta,
                                           Stock = lt.Stock,
                                           NombreCortoMedida = id.NombreCorto,
                                           NombreCategoria = IdCat.Descripcion
    
                                       }).ToList();
    
                    return Listproducs;
                }
            }


    pero cuando hago esta variante 

    public static object Lista()
            {
                using (GourmetEntities db = new GourmetEntities())
                {
                    var Listproducs = (from lt in db.tblProductoes
                                       join id in db.tblUnidads on lt.IdUnidadMedida equals id.Id join IdCat in db.tblCategorias on lt.IdCategoria equals IdCat.Id
                                       select new Producto
                                       {
                                           Codigo = lt.Codigo,
                                           Descripcion = lt.Descripcion,
                                           PrecioVenta = lt.PrecioVenta,
                                           Stock = lt.Stock,
                                           NombreCortoMedida = id.NombreCorto,
                                           NombreCategoria = IdCat.Descripcion
    
                                       }).ToList();
    
                    return Listproducs;
                }
            }

    me vuelven a mostrar todas las columnas todas todas.

    este es el cambio 

    select new Producto

    si lo dejo com object y no con que me devuelva del tipo producto estaría bien.

    Gracias.

    Roberto

    lunes, 23 de marzo de 2020 22:52
  • Ah, vale, ya está claro lo que está sucediendo.

    Cuando devuelves un new Producto y solo inicializas algunas columnas, el objeto "Producto" que devuelves siempre contiene una definición para todas las columnas, lo que pasa es que si no las inicializas en el "new" se quedan con su valor predeterminado (cero si son numéricas, cadena vacía si son strings). Si ese objeto lo tomas y lo asignas al datasource de un grid, entonces el grid lo que hace es pintar en pantalla una columna por cada campo público que exista en el objeto devuelto. No tiene ninguna forma de distinguir si ese campo tiene un cero porque realmente vale cero o porque no has devuelto nada en él desde tu subrutina de acceso a datos.

    Si quieres asignarle al Grid un objeto en el que existen muchas columnas (con independencia de que los valores de dichas columnas hayan sido o no inicializados desde la base de datos) pero solo quieres que el grid muestre algunas de ellas, entonces tienes que ir a las propiedades del Grid y poner false en el "AutoGenerateColumns" y en su lugar acudir a la propiedad Columns y definir cuáles son las que quieres mostrar.

    O, alternativamente, lo que puedes hacer es dejar a true el AutoGenerateColumns y entonces proporcionerle en el DataSource un objeto que solo defina las columnas que quieras mostrar (énfasis en "defina", da igual que las hayas inicializado o no las hayas inicializado con valores tomados desde la base de datos). Ese objeto puede ser anónimo si lo deseas (como hiciste en tu segundo ejemplo), o puede ser una clase definida expresamente con solo los campos que quieres mostrar.

    martes, 24 de marzo de 2020 7:26
    Moderador
  • Muy bien esa respuesta fue de mucha ayuda muchas gracias  Alberto Población

    Roberto

    martes, 24 de marzo de 2020 19:10
  • hola

    >>pero cuando hago esta variante

    porque retornas un object? eso esta mal

    No se trata de una lista de productos, entonces defina una lista de porductos

    public static List<Product> Lista(){ ...

    >>me vuelven a mostrar todas las columnas todas todas.

    en el DataGtridView puedes definir las columnas en tiempo de diseño

    entonces puedes definir las columnas

    Es importante indicar el DataPropertyName y ademas poner en false el AutoGenerateColumns

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 24 de marzo de 2020 19:25
  • Gracias Leandro.

    así fue hecho muy amable

    Roberto

    martes, 24 de marzo de 2020 22:27