Объект с EntityState.Added не возвращается в IRepository <T>.FindAll () - PullRequest
0 голосов
/ 21 августа 2011

Я работаю над небольшим приложением, которое позволяет пользователям создавать список слов, и пользователь может предоставить имя для списка.Я настроил программу, чтобы воспользоваться преимуществом шаблона Unit of Work.Я хочу, чтобы пользователь имел возможность вносить все изменения CRUD, которые он хочет, затем, когда пользователь готов обновить базу данных, нажмите кнопку «Сохранить изменения», чтобы выполнить Context.SaveChanges () и внести все изменения.

Я использую Entity Framework с включенными шаблонами репозитория и единицы работы с отложенной загрузкой.Список и классы слов являются POCO, сопоставленными с моделью данных, которая, в свою очередь, сопоставлена ​​с базой данных.

Мой код добавления:

_unitOfWork.ListRepository.Add(newList);

Метод ListRepository.Add:

public void Add(T newEntity)
{
    _objectSet.AddObject(newEntity);
}

Позже я получаю исключение InvalidOperationException с сообщением: последовательность не содержит элементов.

_unitOfWork.ListRepository.Find(l => l.Name == currentName).Single();

Я знаю, почему я получаю это исключение, потому что для безопасности я должен использовать SingleOrDefault ().Тем не менее, я ЗНАЮ, что сущность, которую я ищу, существует где-то в контексте.Я предполагаю, что я не ищу в нужном месте.

Вот в чем проблема (или мое отсутствие знаний):

Во время отладки я установил точку останова на вышеупомянутом _unitOfWork.ListRepository.Add (newList) код.После перешагивания я пошел в окно «Немедленное окно» и сделал следующее:

?_unitOfWork.ListRepository.FindAll().Count();
1

«1» должен быть «2»

ListRepository.FindAll() метод:

public IQueryable<T> FindAll()
{
    return _objectSet;
}

Я проследил свой код и инициализирую свой объект _unitOfWork только один раз.Я выставил ObjectSet.Context.ObjectStateManager в репозитории, и когда помощник по исключениям появляется в отладке, я могу перейти в Immediate Window и сделать:

_unitOfWork.ListRepository.GetObjectStateManager()
    .GetObjectStateEntries(EntityState.Added).Count();
1

Итак, я знаю, что сущность находится тамно я не уверен, как это сделать с помощью объектов _unitOfWork или ListRepository.Любая помощь будет признательна или, пожалуйста, укажите мне в правильном направлении.

Спасибо.

1 Ответ

2 голосов
/ 21 августа 2011

Так ведет себя EF.Ваши Find и FindAll имеют доступ к ObjectSet экземпляру.Это всегда делает запрос к базе данных - он ничего не делает с сущностями, созданными и еще не вставленными в базу данных, и они не могут быть частью возвращенного результата.

Чтобы получить сущности, которые еще не сохранены, вы должны искать в ObjectStateManager.Вы можете добавить это в свой репозиторий, чтобы разрешить поиск одной сущности.Сначала он будет искать внутреннее хранилище EF, а если объект не будет найден, он будет искать в базе данных:

private T SearchStateManager(Expression<Func<T, bool>> searchCriteria)
{
    return _context.ObjectStateManager.GetObjectStateEntries(~EntityState.Detached)
                                      .Where(e => !e.IsRelationship)
                                      .Select(e => e.Entity)
                                      .OfType<T>()
                                      .SingleOrDefault(searchCriteria.Compile());
} 

public T Single(Expression<Func<T, bool>> searchCriteria)
{
    T entity = SearchStateManager(searchCriteria);
    if (entity == null)
    {
        entity = _objectSet.SingleOrDefault(searchCriteria);
    }

    return entity;
}
...