EF 4: Как обновить отключенный набор данных? - PullRequest
4 голосов
/ 05 мая 2011

Я использую EF 4, POCO. Задача состоит в следующем: иметь длинный набор данных типа DomainObject, которые необходимо извлечь из базы данных и обновить (операции добавления, обновления, удаления) в автономном режиме. Как я могу отправить обновленный набор обратно в базу данных позже? Предположим, что в таблице не было параллельных изменений, так как мы загружаем данные. Я знаю context.SaveChanges () делает обновление, но вопрос в том, как вернуть все изменения в DbSet из своего рода List, или, может быть, есть способ работать напрямую с DbSet в отключенном режиме? Спасибо!

Ответы [ 2 ]

7 голосов
/ 05 мая 2011

Самопроверяемые объекты являются функцией EDMX + ObjectContext API, поэтому, если у вас есть отображение / код, зависящий от DbContext API (вы упомянули DbSet), вы не сможете их использовать. Самостоятельно отслеживаемые объекты являются реализацией шаблона набора изменений (как старый набор данных). Некоторая ссылка на SO:

Если вы не используете объекты самообследования, ответ довольно прост - вы должны сказать EF, какие изменения вы сделали. После использования отдельных сущностей вы должны присоединить сущности обратно к новому контексту и вручную сказать точно, что вы сделали = что вставлено, обновлено, удалено и как вы изменили отношения. Ключевым компонентом в этом процессе является ObjectStateManager в API ObjectContext (context.ObjectStateManager) или DbChangeTracker в API DbContext (context.ChangeTracker). Это очень трудно, когда приходится иметь дело с отношением, поэтому многие из нас обычно используют другой процесс: мы снова загружаем граф сущностей и объединяем изменения из графа отсоединенной сущности в граф присоединенной сущности. Некоторые ссылки:

Имейте в виду, что весь ваш процесс может быть довольно медленным в зависимости от количества обновлений, которые вы хотите сделать. Причина в том, что EF не поддерживает пакетирование команд , поэтому каждая вставка, обновление, удаление выполняется в отдельном цикле передачи в базу данных. Если вы обновите 100 000 сложных объектов, вы можете ожидать, что выполнение SaveChanges займет несколько минут.

Edit:

В некоторых очень особых сценариях, когда вы работаете только с объектами без отношений, вы можете использовать трюк для передачи информации об «изменениях»:

public void ProcessChanges(IEnumerable<DomainObject> entities)
{
    foreach(var entity in entities)
    {
        if (entity.Id == 0)
        {
            // New entity
        }
        else if (entity.Id > 0)
        {
            // Modified entity (you cannot say if entity war really modified,
            // you must update it always).
        }
        else
        {
            // Use negative Id (origId * -1) to mark entity as deleted
            // reverse Id and delete entity
        }
    }
}

Работает только для плоских объектов с простым ключом.

...