2

Just stumbled across the new ClientId (aka client_identifier) variable that is available in Oracle 10g onwards, and would love to incorporate that into an app to assist with audit trails.

The app is using a generated Enterprise Library DAAB based layer (netTiers) that is wired to use the ODP.NET drivers with EntLibContrib, so CRUD functions create an OracleDatabase object and then retrieve generic DbCommand objects from it

It looks like the OracleConnection class has the ClientId property, so what is the cleanest way to get to the Connection object within that pattern? Should I be grabbing the connection out of every DbCommand I create and setting it there, or is that overkill?

Because EntLib is doing much of the connection management behind the scenes, I'm not sure whether I can set the ClientId somewhere outside of the CRUD functions and expect it to persist?

4

1 回答 1

0

如果连接是一个部分类,您可以实现一个触发器,该触发器在连接更改为打开状态时设置客户端 ID。这就是我实现它的方式。

我不知道您是否可以使用其中的一部分:

public partial class DataContext
{
    partial void OnContextCreated()
    {
        if ( null == this.Connection ) return;

        this.Connection.StateChange += Connection_StateChange;
    }
    private EntityConnection EntityConnection
    {
        get { return this.Connection as EntityConnection; }
    }
    private OracleConnection OracleConnection
    {
        get { return this.EntityConnection.StoreConnection as OracleConnection; }
    } 
    private void Connection_StateChange( object sender, StateChangeEventArgs e )
    {
        if ( e.CurrentState != ConnectionState.Open ) return;

        OracleConnection conn = this.OracleConnection;
        if ( null == conn ) return;

        //closes connection on DataContext (bug?), and passes closed/broken connection 
        //conn.ClientId = HttpContext.Current == null ? "Anonymous" : HttpContext.Current.Profile.UserName;

        //working solution
        string identity = HttpContext.Current == null ? "Anonymous" : HttpContext.Current.Profile.UserName;
        OracleCommand cmd = conn.CreateCommand();
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "DBMS_SESSION.SET_IDENTIFIER";
        cmd.Parameters.Add( new OracleParameter { ParameterName = "client_id", Value = identity } );
        cmd.ExecuteNonQuery();
        cmd.Dispose();

        return;
    }

    protected override void Dispose( bool disposing )
    {
        if ( null != this.Connection )
            this.Connection.StateChange -= Connection_StateChange;

        base.Dispose( disposing );
    }
}
于 2011-11-08T14:47:34.670 回答