如何从Devforce IdeaBlade应用程序设置context_info sql语句

时间:2014-06-11 17:20:52

标签: c# winforms linq devforce

我需要从winforms应用程序设置Context_info,这样我就可以通知数据库,如果我的应用程序正在保存记录而不是需要运行触发器的遗留应用程序,则不会运行触发器。我读过的所有内容都说需要使用数据上下文来设置。

在我的应用程序中,我正在使用实体管理器。如何使用实体管理器而不是datacontext设置数据上下文。我只是希望触发器知道它是我的应用程序运行并保存设置触发器的数据

我希望像以下那样做。 “set context_info'0x1234'

在触发器的开始我检查是否设置了context_info并且没有运行触发器。遗产没有设置context_info。

2 个答案:

答案 0 :(得分:3)

我们需要为我们的应用做同样的事情。正如Kim所说,Dev Force论坛中有很多信息。你可以找到我们所做的in this forum post的完整解释,但我会在这里重现这些重要的部分以供参考......

我们的申请中也有类似的要求。在我们的例子中,我们需要在每次打开数据库连接时调用自定义存储过程 - 该过程将标记'与当前活动用户的连接,因为我们有很多需要知道当前用户的触发器(我们使用context_info来完成此操作'标记')。

我们能够在EF Provider Wrapper Toolkit的帮助下处理这个问题(现在似乎也在Nuget上)。这基本上允许您将自己的逻辑注入到各种ADO.NET对象中 - 因此在最低级别的数据库访问中。然后我们制作了自己的自定义DbConnection类,DevForce / EntityFramework最终使用它。它实际上非常简单,并且给了我们很多很好的钩子和#39;进入最低级别的数据库访问已经派上了用场。

以下是我们的自定义DbConnection类的示例代码,它显示了您可以完成的各种事情:

/// <summary>
/// Custom implementation of a wrapper to <see cref="DbConnection"/>.
/// Allows custom behavior at the connection level.
/// </summary>
internal class CustomDbConnection : DbConnectionWrapper
{
    /// <summary>
    /// Opens a database connection with the settings specified by 
    /// the <see cref="P:System.Data.Common.DbConnection.ConnectionString"/>.
    /// </summary>
    public override void Open()
    {
        base.Open();

        //After the connection has been opened, do our logic to prep the connection
        SetContextInfo();

        //...and we do some other stuff not relevant to this discussion
    }

    /// <summary>
    /// Closes the connection to the database. This is the preferred method of closing any open connection.
    /// </summary>
    /// <exception cref="T:System.Data.Common.DbException">
    /// The connection-level error that occurred while opening the connection.
    /// </exception>
    public override void Close()
    {
        //Before closing, we do some cleanup with the connection to make sure we leave it clean
        //   for the next person that might get it....

        base.Close();
    }

    /// <summary>
    /// Attempts to set context_info to the current connection if the user is 
    /// logged in to our application.
    /// </summary>
    private void SetContextInfo()
    {
        //See if a user is logged in
        var user = Thread.CurrentPrincipal as OurCustomUserType;

        //If not, we don't need to do anything - this is probably a very early call in the application
        if (user == null)
            return;

        //Create the ADO.NET command that will call our stored procedure
        var cmd = CreateCommand();
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "p_prepare_connection_for_use";

        //Set the parameters based on the currently logged in user
        cmd.CreateParameter("as_session_id", user.SessionID, null, DbType.Guid);
        cmd.CreateParameter("ai_user_sid", user.UserID, null, DbType.Int32);

        //Run the SP
        cmd.ExecuteNonQuery();
    }

在EF6及更高版本中,可能有一种更简洁的方法来拦截数据库调用....但这种方法多年来一直运作良好。

答案 1 :(得分:0)

虽然IdeaBlade forums已关闭新活动,但它们仍然可以搜索,并且经常包含有关DevForce问题的有用答案和信息。在这种情况下,如果您在那里搜索context_info,您将找到一些有用的线程。其中一个特别展示了如何使用EF Provider Wrapper ToolkitEF 6 DbCommandInterceptor来处理context_info。这些不需要DbContext。