首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有自定义sql-insert vs捕获过程的NHibernate引发的异常和out参数

带有自定义sql-insert vs捕获过程的NHibernate引发的异常和out参数
EN

Stack Overflow用户
提问于 2012-01-31 05:31:03
回答 1查看 587关注 0票数 0

我已经通过过程调用将类映射到自定义sql (插入、删除、更新)。但是,我注意到,当我的插入过程引发异常失败时,来自NHibernate的GenericAdoException没有从该过程中引发我的消息。

但是,所有从delete和update过程引发的异常都被捕获得很好,只有insert过程没有捕获到它的异常消息。

当我们将“原生”Is生成器与自定义NHibernate结合使用时,这是SQL3.2.4的限制还是缺陷?

我也在寻找从过程中获取一些out参数的方法,比如每个事件的时间戳(insert,delete和update),时间戳在过程内部生成。

编辑: OUT PARAMs -我找到了"generated“选项,而不是属性映射选项,我们可以要求NHibernate从过程中获取参数。这意味着这些属性具有泛化值。因此,我尝试使用generated=“总是”,并适用于插入、更新和删除操作。示例:<property name="MyProp" generated="always"/>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-07 03:49:14

我发现当您使用ExecuteReader()运行这些存储过程时,sql server驱动程序不会将存储过程引发的消息放入SqlException中。另一方面,NHibernate使用ExecuteReader()执行自定义的sql-insert (我揭穿了它的源代码),我猜当它与本机(或标识)映射时,获取键是正确且必要的。

那么现在该怎么办呢?我还发现(很难找到) SqlConnection有一个名为"InfoMessage“的事件,在这个事件中,您可以接收(捕获)从存储过程(raiserror)发送的所有消息。现在“捕捉”这些消息是可能的,但是当我们插入一些session.save()时,如何使它们跨越NHibernate核心并被我们的应用程序接收呢?

尽管我们可以访问会话,因此可以访问连接(SqlConnection),但消息已经丢失,因为它们只在事件SqlConnection.InfoMessage发生之前由分配给它的代理接收。

为了解决这个问题,我尝试了两种方法:

  • 在第一个中,我计划了一种在DriverConnectionProvider.GetConnection()中注册委托的方法,这个委托会将消息存储在线程上下文中,将它与连接关联起来,所以这些消息可以在以后获取。
  • 在第二个和选择的那个中,我实现了IDbConnectionIDbCommand,在它们里面包装了SqlConnectionSqlCommand (但我认为NHibernate有一个错误,因为在某些地方它引用了DbConnection而不是IDbConnection -就像<代码>C13中那样,所以我不得不从DbConnection和DbCommand扩展)。

在我的CustomSqlConnection中,我注册了委托并存储消息以供以后使用。这起作用了!既可以作为NHibernate驱动程序使用,也可以作为独立驱动程序使用。

这个想法是:

代码语言:javascript
复制
    public class CustomSqlConnection : DbConnection, IDbConnection {
        private SqlConnection con;
        private StringBuilder str = new StringBuilder(0);

        public CustomSqlConnection() {
            con = new SqlConnection();
            con.InfoMessage += OnInfoMessage;
        }

        private void OnInfoMessage(object sender, SqlInfoMessageEventArgs e) {
            if (str.Length > 0) {
                str.Append("\n");
            }
            str.Append(e.Message);
        }

        public string FetchMessage() {
            string msg = Message;
            str.Clear();

            return msg;
        }

        ...
        ...
    }

编辑:最难的一步是实现来自DdConnection和Dbcommand的所有操作,重新传递对sql实例的调用(查看上面的字段con ),因此:

代码语言:javascript
复制
        ...
        public override void Open() {
            con.Open();
        }
        ...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9071049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档