Entity Framework - исключение обновления - PullRequest
3 голосов
/ 20 апреля 2011

Я только что заметил, что когда SqlException происходит при обновлении данных с использованием Entity Framework, все последующие вызовы SaveChanges завершатся неудачно, поскольку объект, вызвавший исключение, все еще находится в «очереди» для сохранения.

Это просто задело нас в работающей системе, так как многие пользователи не смогли сохранить свои данные из-за какого-то неудачного обновления с ошибкой 'string or binary data would be truncated'. Нам просто пришлось прибегнуть к утилизации пула приложений.

Как я могу удалить / сбросить поврежденный объект и пропустить другие обновления?

РЕДАКТИРОВАТЬ: Еще лучше, каков наилучший способ обработки исключений Sql, которые происходят во время вставки / обновления?

Ответы [ 2 ]

4 голосов
/ 20 апреля 2011

Первое существенное правило EF - ObjectContext - это единица работы, и поэтому вам приходится иметь дело с этим таким образом. Если вы делитесь контекстом между пользователями, вы сделали такую ​​большую ошибку, что вам следует немедленно отключить приложение и не позволять пользователям использовать его, пока вы не исправите его. Я написал ответ , где я описал два шаблона, которые реализует контекст - единица работы и карта идентичности. Если вы разделяете контекст между параллельными пользователями, вы делаете результат каждой операции неопределенным. Вы не можете сказать, есть ли у пользователя свежие / подтвержденные данные, и вы не можете сказать, сохранили ли вы все, что пользователь изменил в одной транзакции.

Теперь контекст использует транзакцию внутренне. Каждый SaveChanges сохраняет каждую измененную запись (от всех одновременных пользователей, если вы разделяете контекст) в транзакции. Одиночная ошибка и вся транзакция откатывается. Как только вы начинаете использовать контекст для логической операции (запрос или действие в случае веб-приложения), вы можете показать пользователю данные и позволить ему внести изменения, или вы можете просто попробовать их снова (в случае решения проблем блокировки). Это, конечно, не решает проблем, когда вы не проверяете пользовательский ввод, потому что это ошибка в приложении, которая должна быть исправлена. Если у вас нет подтверждения, вы не сможете показать пользователю, что не так с данными.

1 голос
/ 20 апреля 2011

Вы можете защитить себя от этой ситуации, следуя шаблону «Единица работы» в своем контексте.

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

Взгляните на:

Использование шаблонов репозитория и единиц работы с Entity Framework 4.0

Единица работы также поможет вам понять, как восстановиться после ошибки.

Поскольку одна единица работы - это, по сути, одна транзакция, вы можете просто откатить транзакцию и уведомить пользователя (и позволить ему изменить свои данные и повторить попытку).

...