¿Cómo forzar a Entity Framework a obtener siempre datos actualizados de la base de datos?

86

Estoy usando la biblioteca EntityFramework.Extended para realizar actualizaciones por lotes. El único problema es que EF no realiza un seguimiento de las actualizaciones por lotes realizadas por la biblioteca. Entonces, cuando vuelvo a consultar DbContext, no devuelve las entidades actualizadas.

Descubrí que usar el AsNoTracking()método mientras se consulta deshabilita el seguimiento y obtiene datos nuevos de la base de datos. Sin embargo, dado que EF no realiza un seguimiento de las entidades consultadas AsNoTracking(), no puedo realizar ninguna actualización de los datos consultados.

¿Hay alguna forma de obligar a EF a obtener los datos más recientes mientras realiza un seguimiento de los cambios?

Saravana
fuente
2
29k visitas y solo 19 votos positivos sobre esto ... bueno, agregué el mío de todos modos
jleach

Respuestas:

148

Intente esto para actualizar una sola entidad:

Context.Entry<T>(entity).Reload()

Editar: para obtener datos nuevos para una colección de entidades, vale la pena intentar eliminar la DbContextinstancia después de cada solicitud.

PlTaylor
fuente
¡Gracias! ¿Hay alguna forma de recargar una colección de entidades en lugar de una? Preferiblemente el entero DbSet.
Saravana
¿Hay algo más que necesite para que esto se considere la respuesta?
PlTaylor
1
Sí, todavía no muestra cómo recargar una colección de entidades.
Saravana
1
¿Ha intentado deshacerse de su dbcontext y crear uno nuevo?
PlTaylor
2
Me tomó horas llegar a esta conclusión. Esa EDITAR en la respuesta es lo que me ayudó a encontrar mi solución. ¡Gracias!
BeemerGuy
17

Me encontré con esta pregunta mientras buscaba una solución a un problema que tenía donde las propiedades de navegación no se completaban después de actualizar la entidad. Cada vez que intentaba recargar la entidad desde la base de datos, tomaba la entrada de la tienda local en su lugar, que no completaba las propiedades de navegación a través de la carga diferida. En lugar de destruir el contexto y recrear uno, descubrí que esto me permitió obtener datos nuevos con los proxies funcionando:

_db.Entry(entity).State = EntityState.Detached;

La lógica detrás de esto era: mi actualización adjuntaba la entidad para que rastreara los cambios. Esto lo agrega a la tienda local. A partir de entonces, cualquier intento de recuperar la entidad con proxies funcionales resultaría en que tomara el local en lugar de salir a la base de datos y devolver una nueva entidad habilitada para proxy. Probé la opción de recarga anterior, que actualiza el objeto de la base de datos, pero eso no le da el objeto proxy con carga diferida. Intenté hacer un Find(id), Where(t => t.Id = id), First(t => t.Id = id). Finalmente, verifiqué los estados disponibles que se proporcionaron y vi que había un estado "Separado". ¡Eureka! Espero que esto ayude a alguien.

Zach
fuente
¿Dónde se aplica el estado Separado para que funcione la carga diferida, por favor? Probé su solución y no funcionó para mí, debo perder algo. Se agradecería su ayuda
Rex
2
Lo descubrí: 1. guardar la entidad, 2. establecer el estado en separado, 3. leer la entidad de la base de datos. ¡Gracias por la pista!
Rex
1

Hacer que el código se ejecute en el mismo contexto no generará entidades actualizadas. Solo agregará nuevas entidades creadas en la base de datos entre ejecuciones. La recarga de fuerza EF se puede hacer así:

ObjectQuery _query = Entity.MyEntity;
_query.MergeOption = MergeOption.OverwriteChanges;
var myEntity = _query.Where(x => x.Id > 0).ToList();
CodeMad
fuente
1

Declaré la variable de entidad, sin asignación, como parte de la clase. Esto me permitió deshacerme de una instancia sin perder la variable como referencia por otros métodos. Me encontré con esto para que no tenga mucho tiempo de ejecución en su haber, pero hasta ahora parece estar funcionando bien.

public partial class frmMyForm
{
    private My_Entities entity;

    public frmMyForm()
    {
        InitializeComponent();
    }

    private void SomeControl_Click(object sender, EventArgs e)
    {
        db.SaveChanges();
        db.Dispose();
        entity = new My_Entities();
        //more code using entity ...
}
Scooter
fuente
0

Para mí ... accedo a mi DbContext así:

_viewModel.Repo.Context

Para obligar a EF a acceder a la base de datos, hago esto:

_viewModel.Repo.Context = new NewDispatchContext();

Sobrescribir el DbContext actual con una nueva instancia. Luego, la próxima vez que utilice mis servicios de datos, obtendrán los datos de la base de datos.

pdschuller
fuente