then related query net lazyloadingenabled lazyload lazy framework efcore disable asp c# entity-framework linq-to-entities entity-framework-6

c# - related - lazyloadingenabled net core



Entity Framework-Stop Lazy Loading Related Entities On Demand? (4)

Tengo Entity Framework configurado y funciona bien la mayor parte del tiempo que lo necesito. Tengo una estructura como esa

public partial class Topic : Entity { public Guid Id { get; set; } public string Name { get; set; } public DateTime CreateDate { get; set; } public virtual Post LastPost { get; set; } public virtual Category Category { get; set; } public virtual IList<Post> Posts { get; set; } public virtual IList<TopicTag> Tags { get; set; } public virtual MembershipUser User { get; set; } public virtual IList<TopicNotification> TopicNotifications { get; set; } public virtual IList<Favourite> Favourites { get; set; } public virtual Poll Poll { get; set; } }

Como pueden ver, tengo varias entidades relacionadas que son listas. Estos se asignan como estándar y se cargan de forma diferida para que pueda llamar a Topic.Posts o Topic.TopicNotifications etc ... (Asignaciones a continuación)

HasOptional(t => t.LastPost).WithOptionalDependent().Map(m => m.MapKey("Post_Id")); HasOptional(t => t.Poll).WithOptionalDependent().Map(m => m.MapKey("Poll_Id")); HasRequired(t => t.Category).WithMany(t => t.Topics).Map(m => m.MapKey("Category_Id")); HasRequired(t => t.User).WithMany(t => t.Topics).Map(m => m.MapKey("MembershipUser_Id")); HasMany(x => x.Posts).WithRequired(x => x.Topic).Map(x => x.MapKey("Topic_Id")).WillCascadeOnDelete(); HasMany(x => x.TopicNotifications).WithRequired(x => x.Topic).Map(x => x.MapKey("Topic_Id")).WillCascadeOnDelete(); HasMany(t => t.Tags) .WithMany(t => t.Topics) .Map(m => { m.ToTable("Topic_Tag"); m.MapLeftKey("TopicTag_Id"); m.MapRightKey("Topic_Id"); });

Esto es todo un bien. Pero en un par de ocasiones tengo la necesidad de llenar manualmente Topic.Posts y Topic.Favorites.

Pero si intento establecer Topic.Posts = SomeCollection , desencadena la carga Topic.Posts = SomeCollection y carga todas las publicaciones primero, y luego me deja configurar mi colección para que se ejecuten dos conjuntos de SQL (el primero no lo quiero)

¿Hay alguna forma de desactivar la carga diferida de forma manual a pedido justo cuando quiero configurar la colección manualmente?

Espero que tenga sentido ...: /


Dado que está utilizando la carga diferida, debe tener proxies generados para sus clases y propiedades de colección.

Reemplazar estas propiedades de colección de proxy con sus propias colecciones me parece un diseño bastante extraño. Pierdes el seguimiento del cambio y probablemente obtengas un par de otros efectos secundarios extraños.

Recomendaría usar proxies / carga lenta y renunciar a la idea de reemplazar las colecciones, o dejar de utilizar proxies y obtener un control total sobre las clases de POCO generadas.

Cuál de los dos enfoques se adapta mejor a sus necesidades depende de su uso general del marco de la entidad.


No conozco un enfoque dirigido a este escenario exacto, así que tendría que ir con una habilitación / deshabilitación temporal de la carga diferida.

using(var context = new MyContext()) { context.Configuration.LazyLoadingEnabled = false; // do your thing using .Include() or .Load() context.Configuration.LazyLoadingEnabled = true; }

Sin embargo, tenga en cuenta que esta es una configuración global, por lo que podría haber un problema de concurrencia si eso sucede en su escenario.


Sería mejor desactivar la carga diferida de forma predeterminada y en su lugar especificar cuándo desea cargar los datos adicionales en primer lugar. EF está configurado para permitir la carga Eager utilizando la función .Include () en su consulta, con la carga diferida puede desordenarse si la enciende / apaga para varias funciones, es mejor que simplemente la apague y administre qué / cuándo quieres cargar los datos si sientes la necesidad de apagarlos.

Consulte https://msdn.microsoft.com/en-nz/data/jj574232.aspx para obtener ejemplos específicos y un desglose de las diferentes formas en que puede cargar los datos de carga lenta / lenta. El primer ejemplo muestra cómo puedes sacar mensajes de un blog, que es similar a lo que quieres lograr.

var topics = context.Topics .Include(t => t.Posts) .ToList();


No recomendaría desactivar la carga de holgazanería por solicitud. Como AllMadHare sugiere, puede desactivar completamente la carga diferida, pero eso podría forzar cambios en la forma de cargar todos los datos. Recomendaría eliminar la palabra clave virtual de Publicaciones para que su clase se vea así:

public partial class Topic : Entity { public Guid Id { get; set; } public string Name { get; set; } public DateTime CreateDate { get; set; } public virtual Post LastPost { get; set; } public virtual Category Category { get; set; } public IList<Post> Posts { get; set; } public virtual IList<TopicTag> Tags { get; set; } public virtual MembershipUser User { get; set; } public virtual IList<TopicNotification> TopicNotifications { get; set; } public virtual IList<Favourite> Favourites { get; set; } public virtual Poll Poll { get; set; } }

De acuerdo con la documentación que se encuentra aquí: https://msdn.microsoft.com/en-us/data/jj574232.aspx#lazyOffProperty esto le permitirá cargar otras propiedades de navegación y publicaciones de carga impacientes si es necesario.