Entity Framework Обновление существующего объекта

Я добавил строку в свою базу данных и вернулся с другим контекстом, чтобы обновить его. У меня есть этот класс:

public abstract partial class DataManager<I, C> 
    where C : class, IDomainObject, I, new( ) where I : IDomainObject

C может быть EntityObject, но этот класс не знает этого.

Мое сохранение выглядит так:

    public virtual bool Save( I _item )
    {
        bool rc = true;
        try
        {
        var set = m_Context.GetObjectSet<I, C>( );
        ObjectStateEntry stateEntry = null;
        if( ! m_Context.ObjectStateManager.TryGetObjectStateEntry( ( C ) _item, out stateEntry ) )
        {
            if( _item is EntityObject )
            {
                    if ( _item.IsNew )
                    {
                        set.AddObject( ( C ) _item );
                    }
                    else
                    {
                        try
                        {
                            set.Attach( ( C ) _item );
                        }
                        catch( Exception ex )
                        {
                            set.ApplyCurrentValues( ( C ) _item );
                        }

и так далее...

В моем тестовом случае stateEntry не найдено TryGetObjectStateEntry. Это, однако, EntityObject, и он не новый (IsNew - мой флаг), поэтому он попадает в другое. Вот моя проблема: set.Attach выдает эту ошибку

"Объект с таким же ключом уже существует в ObjectStateManager. ObjectStateManager не может отслеживать несколько объектов с одним и тем же ключом".

и в следующий же момент ApplyCurrentValues ​​выдает это:

"Объект с ключом, который совпадает с ключом предоставленного объекта, не может быть найден в ObjectStateManager. Убедитесь, что значения ключа предоставленного объекта соответствуют значениям ключа объекта, к которому должны применяться изменения".

Как это может быть правдой?

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ:

_item был создан Get в другом контексте. Этот контекст был тогда ликвидирован. На тот момент _item имел EntityState.Unchanged. Я применил некоторые изменения к нему, и он изменился на EntityState.Modified. (Я не ожидал, что, поскольку контекст (и его ObjectStateManager) должен был исчезнуть.) Во всяком случае, когда он достигает Save (выше), его состояние (как сообщается отладчиком) изменяется, но я имею новый контекст к тому времени. Если я получу список ВСЕХ ObjectStateEntries (Добавлено, Удалено, Изменено, Без изменений) на данный момент, их всего два, и _item не является одним из них, как сообщает ApplyCurrentValues, но его нельзя присоединить, потому что "это тоже там! Возможно, проблема в том, что он все еще прикреплен к старому ObjectStateManager (может быть какая-то ссылка, которая не позволяет утилизировать ObjectStateManager?).

2 ответа

Проблема состоит в том, что каждый раз, когда db-контекст инициализируется, он берет строки из базы данных и каждый ряд, назначая ключ сущности. это означает, что одна и та же строка, полученная с помощью 2 db-context, будет иметь 2 разных ключа объекта. ключ объекта подобен идентификатору в структуре объекта и используется вместо идентификатора рассматриваемого объекта. Но ограничения таблиц хотя и сохраняются (без дублирования первичного ключа). Надеюсь, это имеет смысл.

Проблема заключается в том, что вы присоединяете двух разных пользователей к одной и той же организации, однако в каждом случае объект org является отдельным экземпляром.

Если организация уже находится в БД, попробуйте:

  1. Либо задайте для свойств навигации для организации значение NULL и задайте только свойства OrganizationId.

  2. Или загрузите организационную сущность из БД и поместите в нее реквизиты навигации.

Если организации нет в БД:

Используйте тот же экземпляр (выбросьте один и замените его другим).

Другие вопросы по тегам