Могу ли я переопределить Dispose для создания класса сущности, который всегда вызывает SaveChanges? - PullRequest
3 голосов
/ 13 сентября 2011

Это довольно тонкий момент, и я ожидаю, что ответ «это не самая горячая идея для начала» - это говорит о том, что у меня есть моменты, которые меня интересуют независимо от того, достаточно ли добр, чтобы побаловать себя.

Код модели:

public partial class MyEntities : ObjectContext
{
    // the idea is if the object is in a using block, this always gets called?
    protected override void Dispose(bool disposing)
    {
        this.SaveChanges();
        base.Dispose(disposing);
    }
}

Код клиента:

using(var model = new MyEntities())
{
   // do something

   // no worry about calling model.SaveChanges()
}

Проблемы, в которых я не уверен:

  1. Утилизируйте правильное место, чтобы сделать это, потому что я почему-то думал «Завершить» - я всегда путаюсь с уничтожением C #.

  2. В случае, если в клиентском коде выдается исключение, обычно SaveChanges пропускается, и это хорошо, но если это работает так, как я думаю, оно всегда будет вызывать его. Стоит ли использовать try с пустым уловом?

    public partial class MyEntities : ObjectContext
    {
        protected override void Dispose(bool disposing)
        {
            try
            {
               this.SaveChanges();
            }
            catch {}
            base.Dispose(disposing);
        }
    }
    

Ответы [ 2 ]

13 голосов
/ 13 сентября 2011

Не делай этого. Это плохая идея.

Цель «Утилизация» состоит в том, чтобы вежливо утилизировать неуправляемый ресурс как можно раньше, чтобы другие процессы могли его использовать. «Dispose» не должен иметь семантику - он не должен изменять состояние вашей программы или быть каким-либо образом обязательным. Он должен делать только то, что говорит: распоряжаться ресурсом .

Должны ли вы сделать это в финализаторе? Абсолютно нет . Это еще хуже. Финализатор может вообще не работать, финализатор работает в другом потоке, финализатор может быть вызван, даже если объект не был должным образом инициализирован, и так далее. Написание финализатора почти никогда не является правильным решением, и если вы действительно пишете финализатор, он должен распоряжаться только ресурсом. Не делайте ничего сложного в финализаторе; почти наверняка вы напишете опасно неправильную и хрупкую программу.

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

0 голосов
/ 13 сентября 2011
  1. Утилизация - это место, где вы бы это делали, если бы вообще это делали.

  2. Это одна из причин, по которой вам следует не делать это.

...