3

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

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

我想做如下。“设置 context_info '0x1234'

在触发器开始时,我检查是否设置了 context_info 并且不运行触发器。旧版没有设置 context_info。

4

2 回答 2

3

我们需要为我们的应用程序做同样的事情。正如 Kim 所说,Dev Force 论坛中有很多信息。您可以在此论坛帖子中找到我们所做工作的完整说明,但我将在此处复制重要部分以供参考...

我们的应用程序中有类似的要求。在我们的例子中,每次打开数据库连接时,我们都需要调用自定义存储过程——该过程将“标记”与当前活动用户的连接,因为我们有很多需要知道当前用户的触发器(我们使用context_info 来完成这个“标记”)。

我们能够在EF Provider Wrapper Toolkit的帮助下处理这个问题(现在似乎也在Nuget上)。这基本上可以让您将自己的逻辑注入到各种 ADO.NET 对象中——因此在数据库访问的最低级别。然后,我们制作了 DevForce/EntityFramework 最终使用的自定义 DbConnection 类。它实际上非常简单,并且为我们提供了很多很好的“挂钩”到最低级别的数据库访问,这些都派上了用场。

下面是我们的自定义 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 及更高版本中,可能有一种更简洁的方法来拦截数据库调用......但这种方法多年来一直很好用。

于 2014-06-20T20:50:45.710 回答
0

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

于 2014-06-11T21:44:08.530 回答