En EntityFramework, ¿es posible consultar los objetos que acaban de agregarse al contexto utilizando AddObject pero antes de llamar al método SaveChanges?Consultar objetos después de AddObject antes de SaveChanges?
Gracias
En EntityFramework, ¿es posible consultar los objetos que acaban de agregarse al contexto utilizando AddObject pero antes de llamar al método SaveChanges?Consultar objetos después de AddObject antes de SaveChanges?
Gracias
puede consultar objetos de este tipo,
context.ObjectStateManager.GetObjectStateEntries(EntityState.Added).Select(obj => obj.Entity).OfType<TheEntityType>()
esto va a consultar los objetos que están en estado de agregado. Si quiere otros estados también puede pasar todos los demás estados al método GetObjectStateEntries
de esta manera.
GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Unchanged)
a persistir una entidad que por lo general lo agrega a su DbSet
en el contexto.
Por ejemplo
var bar = new Bar();
bar.Name = "foo";
var context = new Context();
context.Bars.Add(bar);
Sorprendentemente, la consulta context.Bars
, la entidad acaba de agregar no se puede encontrar
var howMany = context.Bars.Count(b => b.Name == "foo");
// howMany == 0
Después context.SaveChanges()
la misma línea resultará 1
El DbSet
parece no darse cuenta de los cambios hasta que persistan en db.
Afortunadamente, cada DbSet
tiene una propiedad Local
que actúa como el DbSet
en sí, sino que reflejan todas las operaciones en memoria
var howMany = context.Bars.Local.Count(b => b.Name == "foo");
// howMany == 1
También puede utilizar Local
añadir entidades
context.Bars.Local.Add(bar);
y deshacerse del comportamiento extraño de Entity Framework.
En las instancias transitorias de hibernación ya están asociadas al contexto. Acabo de tropezar con esta restricción EF.
No logré intersecar/unir el ObjectSet
con sus entidades transitorias ObjectSet.Local
pero para nuestro caso de uso el siguiente método de búsqueda es suficiente.
En nuestros casos creamos algunas entidades perezoso en función de criterios únicos durante una iteración
método Find
Si está utilizando un patrón de repositorio que puede crear un método como:
public interface IRepository<T> where T : class, IEntity
{
/// <summary>
/// Finds the unique Entity with the given predicate.
/// Depending on implementation also checks transient/local (unsaved) Entities.
/// </summary>
/// <param name="predicate"></param>
/// <returns></returns>
IQueryable<T> FindAll(Expression<Func<T, bool>> predicate);
}
public class EfRepository<T> : IRepository<T> where T : class, IEntity
{
protected readonly ObjectContext context;
protected readonly ObjectSet<T> objectSet;
/// <summary>
/// Creates a new repository of the given context.
/// </summary>
/// <param name="context"></param>
public EfRepository(ObjectContext context)
{
if (context == null)
throw new ArgumentException("Context must not be null.");
this.context = context;
this.objectSet = context.CreateObjectSet<T>();
}
/// <summary>
/// Also takes local context into consideration for unsaved changes
/// </summary>
/// <param name="predicate"></param>
/// <returns></returns>
public T Find(Expression<Func<T, bool>> predicate)
{
T result = this.objectSet.Where(predicate).FirstOrDefault();
if (result == null)
result = this.objectSet.Local().Where(predicate).FirstOrDefault();
return result;
}
}
¿Esto devuelve tanto el Agregado pero no guardado como los elementos de la base de datos? – BlackICE
'context.Bars.Local' está inicialmente vacío, hasta que' context.Bars' se carga desde la base de datos. Luego puede tener elementos en memoria y elementos de la base de datos. No se recomienda usar Local en un conjunto de datos grande. Más información acerca de Local: https://msdn.microsoft.com/en-us/data/jj592872 – Aximili
¿Es esto específico para una versión de EF pasado 4?No tengo una propiedad 'Local' en mi' ObjectSet', pero también tengo objetos 'ObjectSet' y' ObjectContext', no 'DbSet' y' DbContext'. –