powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / NHibernate: custom insert / update / delete
6 сообщений из 6, страница 1 из 1
NHibernate: custom insert / update / delete
    #37288346
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток

Есть БД на Oracle 11g, доступ к которой осуществляется с помощью NHibernate. Проблема в том, что создание/изменение/удаление записей в таблицах БД осуществляется через хранимые процедуры, у которых масса параметров типа OUT. Вызовы ХП в NHibernate удалось "прикрутить" следующим образом:
Хранимая процедура - обновление сущности
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CREATE OR REPLACE PACKAGE BODY PKG_AUTHORS AS
...

PROCEDURE AUTHOR_MOD(
	pID IN NUMBER,
	pName IN VARCHAR2,
	pErrCode OUT VARCHAR2,
	pErrMsg OUT VARCHAR2) 
IS
BEGIN
  UPDATE authors SET name = pName, updated_date = CURRENT_TIMESTAMP 
   WHERE id = pID;

	COMMIT;
EXCEPTION 
	WHEN OTHERS THEN 
		pErrCode := SQLCODE;
		pErrMsg := SQLERRM;
END;
...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
public static string OraCode { get; set; }
public static string OraMessage { get; set; }

// изменение сущности 'Author'
public static void AuthorMod(Author a, ISession session)
{
    ITransaction transaction = null;
    try
    {
        // execute stored procedure
        OracleCommand command = session.Connection.CreateCommand() as OracleCommand;

        transaction = session.BeginTransaction();
        transaction.Enlist(command);

        command.CommandType = CommandType.StoredProcedure;
        command.CommandText = "PKG_AUTHORS.AUTHOR_MOD";

        OracleParameter p = command.Parameters.AddWithValue("pId", a.Id);
        p = command.Parameters.AddWithValue("pName", a.Name);

        p = command.Parameters.Add("pErrCode", OracleType.VarChar);
        p.Direction = ParameterDirection.Output;
        p.Size = sizeof(char) * 8096;
        p = command.Parameters.Add("pErrMsg", OracleType.VarChar);
        p.Direction = ParameterDirection.Output;
        p.Size = sizeof(char) * 8096;

        int ret = command.ExecuteNonQuery();
        transaction.Commit();

        // save possible Oracle error
        OraCode = command.Parameters[2].Value as string;
        OraMessage = command.Parameters[3].Value as string;
    }
    catch (Exception e)
    {
        if (transaction != null && transaction.IsActive)
            transaction.Rollback();
        throw;
    }
}

Проблема в том, что после вызова метода AuthorMod ядро NHibernate выполняет еще один, свой собственный, Update той же записи в БД, что явно избыточно. Отсюда вопросы
1) Как можно для NHibernate отметить данный экземпляр, как уже сохраненный? Т.е. вызвал свой метод обновления, потом отметил, что экземпляр сохранен (IsDirty = false или нечто вроде).
2) Есть ли более толковый вариант вызова ХП с параметрами типа OUT из NHibernate?

Я пробовал в hbm.xml файле указывать атрибут mutable="false" в привязке класса, однако в этом случае собственный NHibernate'овский Update вызывается ДО вызова ХП из метода AuthorMod, а не после, что имело место до добавления mutable="false". Кроме того, мне нужно вызывать ХП не только для INSERT / UPDATE / DELETE, но и для выполнения других задач, не хочется после каждого вызова получать очередной Update из сущности в запись БД.

Тестовый проект для .NET 4.0 / MSVS 2010: http://depositfiles.com/files/t5dmdbwm8
...
Рейтинг: 0 / 0
NHibernate: custom insert / update / delete
    #37288962
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JohnSparrow,

тут и тут .
...
Рейтинг: 0 / 0
NHibernate: custom insert / update / delete
    #37289952
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor, спасибо за подсказку, но мне нужно немного не то. В данном случае хранимые процедуры имеют OUT-параметры, а с ними NHibernate не работает. Нужно просто сделать так, чтобы после вызова моих ХП NHibernate не выполнял собственные Update той же сущности в БД.
...
Рейтинг: 0 / 0
NHibernate: custom insert / update / delete
    #37290015
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще-то все успешно работает, если вызов ХП не оборачивать в транзакцию NHibernate, т.е. из приведенного выше листинга метода AuthorMod на C# убрать строчки
Код: plaintext
1.
2.
transaction = session.BeginTransaction();
transaction.Enlist(command);

Но как бы неправильно использовать такие вот решения, полученные методом научного тыка.
...
Рейтинг: 0 / 0
NHibernate: custom insert / update / delete
    #37290195
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JohnSparrow,

Попробуйте покопать в сторону IInterceptor. Хотя я не понимаю, зачем вам NH, если вы даже CRUD операции собираетесь выполнять через хранимки.
...
Рейтинг: 0 / 0
NHibernate: custom insert / update / delete
    #37291005
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запросы удобнее делать через NH, через напрямую через ADO.NET.
Кроме того, UI окна отчета, состоящего из панели фильтра и грида, замечательно коррелирует со средствами ICriteria.

Есть, правда, вариант переместить бизнес-логику из БД в сервер приложений, тогда можно использовать "идеологически чистый" NHibernate, :)
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / NHibernate: custom insert / update / delete
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]