В EntityFramework можно запросить объекты, которые только что были добавлены в контекст с помощью AddObject, но перед вызовом метода SaveChanges?
Спасибо
В EntityFramework можно запросить объекты, которые только что были добавлены в контекст с помощью AddObject, но перед вызовом метода SaveChanges?
Спасибо
вы можете запросить объекты, подобные этому,
context.ObjectStateManager.GetObjectStateEntries(EntityState.Added).Select(obj => obj.Entity).OfType<TheEntityType>()
это запросит объекты, которые находятся в добавленном состоянии. Если вы хотите и другие состояния, вы можете передать все остальные состояния методу GetObjectStateEntries
, как это.
GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Unchanged)
Чтобы сохранить сущность, вы обычно добавляете ее в контекст DbSet
.
Например,
var bar = new Bar();
bar.Name = "foo";
var context = new Context();
context.Bars.Add(bar);
Удивительно, но при запросе context.Bars
только что добавленный объект не может быть найден
var howMany = context.Bars.Count(b => b.Name == "foo");
// howMany == 0
После context.SaveChanges()
та же строка приведет к 1
DbSet
кажется неосведомленным об изменениях, пока они не сохранятся на БД.
К счастью, у каждого DbSet
есть свойство Local
, которое действует как сам DbSet
, но оно отражает все операции в памяти
var howMany = context.Bars.Local.Count(b => b.Name == "foo");
// howMany == 1
Вы также можете использовать Local
для добавления сущностей
context.Bars.Local.Add(bar);
и избавиться от странного поведения Entity Framework.
В hibernate временные экземпляры уже привязаны к контексту. Просто наткнулся на это ограничение EF.
Мне не удалось пересечь/объединить ObjectSet
с его временными объектами ObjectSet.Local
, но для нашей утилиты достаточно найти метод поиска ниже.
В наших случаях мы создаем несколько объектов, ленивых, в зависимости от уникальных критериев во время итерации
Найти метод
Если вы используете шаблон репозитория, вы можете создать такой метод, как:
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;
}
}