none
problema lazy loading EF c# RRS feed

  • Pregunta

  • Edito el tema para especificar mejor..

    si yo hago por ejemplo una select de todos los campos, puedo leer el nombre de la ciudad?? porque me da error como que "ciudades" es null

    List<Clientes> lista= (from C in db.Clientes select C).ToList();

    EDIT: la excepción que tengo es "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."

     dado que tengo el proyecto separado en capas.. cuando llego a la capa de presentación con mi lista de clientes, al usar lazy loading no puedo acceder a las "ciudades" desde esta capa porque no puede conectarse a la bd.., eso es lo que entiendo.. no se como manejarlo entonces

    Capa de presentación:

    //parte del codigo de la capa de presentación..
    List<Clientes> clientes = ClientesCN.listarClientes();
    foreach(var cliente in clientes)
    {
    //otros campos
    txtCiudad.text=cliente.Ciudades.nombre;//en esta linea arroja error porque Ciudades es null
    }


    saludos





    jueves, 27 de junio de 2019 22:35

Todas las respuestas

  • Pero no entiendo la duda

    Si tienes dos entidades que representan dos tablas de la ase de datos y estan las llaves foraneas y las propiedades de navegacion EF cuando generas la consulta te trae la propiedad de navegacion osea el id y su descripcion.

    Como esta tu modelo de entidades???

    jueves, 27 de junio de 2019 22:51
  • Pero no entiendo la duda

    Si tienes dos entidades que representan dos tablas de la ase de datos y estan las llaves foraneas y las propiedades de navegacion EF cuando generas la consulta te trae la propiedad de navegacion osea el id y su descripcion.

    Como esta tu modelo de entidades???

    yo tengo las entidades que me genera EF usando el enfoque Database first

    por ejemplo la entidad Clientes

        public partial class Clientes
        {
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
            public Clientes()
            {
                this.Socios = new HashSet<Socios>();
            }
        
            public int idCliente { get; set; }
            public int idCiudad { get; set; }
            public Nullable<int> idCalle { get; set; }         
            public virtual Calles Calles { get; set; }
            public virtual Ciudades Ciudades { get; set; }
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
            public virtual ICollection<Socios> Socios { get; set; }
        }
    si puedo acceder a la descripcion navegando como dices.. pero no puedo armar un List<Clientes> con esa "descripcion de la ciudad" porque mi Entidad "Clientes" no tiene tal propiedad

    jueves, 27 de junio de 2019 22:57
  • si la tienes

    public virtual Ciudades Ciudades { get; set; }

    esa es la propiedad de navegacion

    viernes, 28 de junio de 2019 0:11
  • si la tienes

    public virtual Ciudades Ciudades { get; set; }

    esa es la propiedad de navegacion


    Si pero esa la verdad no se como usarla cuando hago la consulta a la bd
    viernes, 28 de junio de 2019 0:54
  • Hola

    en entiity framework cuando defines virtual utilizas lazy loading,

    osea aotomaticamente te carga las ciudad

    seria algo asi mas o menos

    List<Clientes> lista= (from C in db.Clientes select C.cliente,C.Ciudades.nombreCiudad).ToList();
    string city = lista[0].Ciudades.Cuidad;

    espero resuelva tu problema
    viernes, 28 de junio de 2019 1:32
  • Hola

    en entiity framework cuando defines virtual utilizas lazy loading,

    osea aotomaticamente te carga las ciudad

    seria algo asi mas o menos

    List<Clientes> lista= (from C in db.Clientes select C.cliente,C.Ciudades.nombreCiudad).ToList();
    string city = lista[0].Ciudades.Cuidad;

    espero resuelva tu problema

    si yo hago por ejemplo una select de todos los campos, puedo leer el nombre de la ciudad?? porque me da error como que "ciudades" es null

    List<Clientes> lista= (from C in db.Clientes select C).ToList();

    EDIT: la excepción que tengo es "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."

     dado que tengo el proyecto separado en capas.. cuando llego a la capa de presentación con mi lista de clientes, al usar lazy loading no puedo acceder a las "ciudades" desde esta capa porque no puede conectarse a la bd.., eso es lo que entiendo.. no se como manejarlo entonces

    Capa de presentación:

    //parte del codigo de la capa de presentación..
    List<Clientes> clientes = ClientesCN.listarClientes();
    foreach(var cliente in clientes)
    {
    //otros campos
    txtCiudad.text=cliente.Ciudades.nombre;//en esta linea arroja error porque Ciudades es null
    }


    viernes, 28 de junio de 2019 16:27
  • Hola intenta con esto

    List<Clientes> lista= db.Clientes.Include(c=>c.Ciudades).ToList(); 
    string city = lista[0].Ciudades.Cuidad;

    sábado, 29 de junio de 2019 1:26
  • hola

    Podrias usar el Include() para cargar la propiedad de navegacion a las Ciudades

    Entonces quedaria

    List<Clientes> lista= db.Clientes.Include(x=> x.Ciudades).ToList();

    Esto se explica aqui

    Cargar entidades relacionadas


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    sábado, 29 de junio de 2019 3:54
  • Creo que entiendo lo que te pasa, si te fijas en el error, te dice exactamente lo que esta pasando, la “instancia” del ObjetoContexto esta desconectado, es decir que necesita estar conectado para realizar la operación.

    Primero hay que entender que LazyLoading, no trae las propiedades de navegación marcadas como Virtual hasta exactamente el momento que accedes a ellas. Te doy un ejemplo para que lo veas:

    List<Clientes> MisClientes;

    using (var db= new DbContextoDatos())

    {

    MisClientes = db.Clientes.ToList(); // aquí traes tus clientes, pero no las propiedades de navegación.

          

    var MisCiudades = MisClientes.Ciudades.ToList(); // ahora es cuando Lazy consulta por la propiedad de navegación. / en este caso funciona porque el contexto db sigue instanciado.

    }        

    Ahora bien, el mismo caso anterior pero accediendo fuera de la instancia del contexto:

    using (var db= new DbContextoDatos())

    {

    MisClientes = db.Clientes.ToList(); // aquí traes tus clientes, pero no las propiedades de navegación.

    }        

    var MisCiudades = MisClientes.Ciudades.ToList(); // aquí te arroja el error, porque cuando quiere acceder a la propiedad Ciudades, el objeto db, ya no esta instanciado.

    No importa que lo hagas en distintas capas del proyecto (datos, presentación, etc, lo importante es que cuando accedas a la propiedad Virtual por Lazy, el contexto siga intanciado.

    Para evitar esto, es preferible usar Include:

    MisClientes = db.Clientes.Include(“Ciudades”).ToList();

    Ó

    MisClientes = db.Clientes.Include(c=>c.Ciudades).ToList();

    De esta forma traes todas las ciudades de una vez al cargar los Clientes, y evitas posibles problemas de rendimiento con el N+1, pero ese es otro tema para explicar.

    Espero se entienda.

    Saludos

    sábado, 29 de junio de 2019 3:59