Usuario
problema lazy loading EF c#

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
- Editado Artemis Spectrum viernes, 28 de junio de 2019 17:12
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???
-
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
-
-
-
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 -
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 }
- Editado Artemis Spectrum viernes, 28 de junio de 2019 17:10
-
-
hola
Podrias usar el
Include()
para cargar la propiedad de navegacion a las CiudadesEntonces quedaria
List<Clientes> lista= db.Clientes.Include(x=> x.Ciudades).ToList();
Esto se explica aqui
Leandro Tuttini
Blog
MVP Profile
Buenos Aires
Argentina -
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