2011-08-09 8 views

Respuesta

10

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) 
23

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.

+3

¿Esto devuelve tanto el Agregado pero no guardado como los elementos de la base de datos? – BlackICE

+0

'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

+0

¿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'. –

1

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; 
    } 
} 
Cuestiones relacionadas