我已经通过过程调用将类映射到自定义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"/>
发布于 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()中注册委托的方法,这个委托会将消息存储在线程上下文中,将它与连接关联起来,所以这些消息可以在以后获取。IDbConnection和IDbCommand,在它们里面包装了SqlConnection和SqlCommand (但我认为NHibernate有一个错误,因为在某些地方它引用了DbConnection而不是IDbConnection -就像<代码>C13中那样,所以我不得不从DbConnection和DbCommand扩展)。在我的CustomSqlConnection中,我注册了委托并存储消息以供以后使用。这起作用了!既可以作为NHibernate驱动程序使用,也可以作为独立驱动程序使用。
这个想法是:
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 ),因此:
...
public override void Open() {
con.Open();
}
...https://stackoverflow.com/questions/9071049
复制相似问题