транзакции и удалить, используя свободный nhibernate - PullRequest
1 голос
/ 20 мая 2010

Я начинаю играть с (свободно) nHibernate, и мне интересно, если кто-то может помочь со следующим. Я уверен, что это полный вопрос.

Я хочу сделать:

   delete from TABX where name = 'abc'

, где таблица TABX определяется как:

   ID int
   name varchar(32)
   ...

Я строю код на основе интернет-примеров:

 using (ITransaction transaction = session.BeginTransaction())
                {
                    IQuery query = session.CreateQuery("FROM TABX WHERE name = :uid")
                        .SetString("uid", "abc");
                    session.Delete(query.List<Person>()[0]);
                    transaction.Commit();
                }

но, увы, он генерирует два запроса (один выбор и один удаление). Я хочу сделать это в одном выражении, как в моем исходном SQL. Как правильно это сделать?

Кроме того, я заметил, что в большинстве примеров в Интернете люди, как правило, всегда заключают все запросы в транзакции. Это почему? Если я выполняю только одно заявление, это кажется излишним. Люди склонны просто бездумно вырезать и вставлять, или есть какая-то причина? Например, в моем запросе выше, если мне удастся получить его от двух запросов до одного, я смогу удалить транзакцию начала / принятия, нет?

если это имеет значение, я использую PostgreSQL для экспериментов.

Ответы [ 3 ]

2 голосов
/ 20 мая 2010

Ваш первый запрос поступил с query.List<Person>().

Ваше фактическое заявление об удалении исходит от session.Delete(...)

Обычно, когда вы имеете дело только с одним объектом, вы используете Load () или Get ().

Session.Load(type, id) создаст объект для вас, не ища его в базе данных. Однако, как только вы получите доступ к одному из свойств объекта, он будет гидратировать объект.

Session.Get(type, id) действительно найдет данные для вас.

Что касается транзакций, это хорошая статья, объясняющая, почему хорошо обернуть все ваши запросы nHibernate транзакциями.

http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions

2 голосов
/ 20 мая 2010

Вы можете сделать удаление за один шаг с помощью следующего кода:

session.CreateQuery("DELETE TABX WHERE name = :uid")
       .SetString("uid", "abc")
       .ExecuteUpdate();

Однако, делая это таким образом, вы избегаете вызовов прослушивателей событий (это просто сопоставлено с простым вызовом SQL), обновлений кэша и т. Д.

0 голосов
/ 20 мая 2010

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

Что касается упаковки всего в транзакции: в большинстве баз данных транзакции в любом случае неявны для каждого запроса. Явные транзакции являются лишь гарантией того, что данные не будут изменены из-под вашей операционной деятельности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...