Я работаю над веб-сайтом ASP.NET MVC и использую Entity Framework для сохранения / обновления данных в моей базе данных.

Я использую ninject для внедрения dbContext в свой класс репозитория, как показано ниже:

public class MyRepository : IMyRepository
{
    MyContext _context;

    public MyRepository(MyContext context)
    {
        _context = context;
    }

    // more code ...

Вот как я ввожу контекст с помощью ninject:

kernel.Bind<MyContext>().ToSelf().InSingletonScope();

И я использую введенный dbContext, как показано ниже, чтобы сохранить данные в моей базе данных:

public void InsertModel(MyModel r)
{
    _context.MyModel.Add(r);
    _context.SaveChanges();
}

Теперь проблема, с которой я столкнулся , заключается в том, что если возникает исключение (например, если я намеренно передаю недопустимую модель), Entity Framework генерирует исключение. Недопустимый объект остается в dbContext, и все дальнейшие попытки сохранения завершатся ошибкой из-за этого.

Я искал эту проблему в Google и нашел эту статью который предлагает поместить операцию save / update в блок try / catch. Если возникает какое-либо исключение, предлагается очистить dbContext в блоке catch.

Это правильная оценка? Похоже, придется много работать, чтобы поставить try / catch вокруг каждой операции save и очистить dbContext? Буду признателен за любую помощь в объяснении правильного подхода к очистке контекста.

0
user9157250 31 Дек 2017 в 02:36

2 ответа

Лучший ответ

Вам необходимо создать один dbContext для каждого веб-запроса. Не используйте свой dbContext для разных запросов: управление жизненным циклом dbContext

DbContext легкий и недорогой в создании, поэтому не беспокойтесь о производительности: MSDN

Если вы используете ninject, вы можете использовать InRequestScope вместо InSingletonScope . InRequestScope гарантирует, что время жизни вашего Entity Framework dbContext не превышает времени существования вашего Http WebRequest, и удаляет ваш dbContext в конце каждого запроса.

kernel.Bind<MyContext>().ToSelf().InRequestScope();

Боковое примечание : если вы используете шаблон репозитория, убедитесь, что вы используете InRequestScope для своего репозитория. Репозиторий зависит от dbContext, и вы столкнетесь с проблемой, если ваш dbContext будет удален, пока репозиторий все еще используется.

kernel.Bind<IMyRepository>().To<MyRepository>().InRequestScope();
1
Hooman Bahreini 13 Мар 2018 в 03:31

Был бы признателен за любую помощь в объяснении правильного подхода к очистке контекста.

Ваш DbContext должен быть привязан к одному веб-запросу и будет уничтожен в конце запроса.

1
David Browne - Microsoft 31 Дек 2017 в 16:50