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

Есть БД на 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
01.06.2011, 12:21
    #37288962
SolYUtor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate: custom insert / update / delete
JohnSparrow,

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

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

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

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


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