Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual studio 2012 实体框架5-实现SQL Server“;“以用户身份执行”;_Visual Studio 2012_Sql Server 2008 R2_Entity Framework 5_Impersonation - Fatal编程技术网

Visual studio 2012 实体框架5-实现SQL Server“;“以用户身份执行”;

Visual studio 2012 实体框架5-实现SQL Server“;“以用户身份执行”;,visual-studio-2012,sql-server-2008-r2,entity-framework-5,impersonation,Visual Studio 2012,Sql Server 2008 R2,Entity Framework 5,Impersonation,我正在使用Visual Studio 2012、Entity Framework 5和SQL Server 2008编写一个数据库应用程序。我希望实体框架模拟SQL Server用户(即未登录的用户)。我已经为DB contextMyDatabaseEntities创建了一个新的构造函数,其中包含一个用于模拟用户名称的参数。以下是我编写的代码: public partial class MyDatabaseEntities { private String _impersonateUse

我正在使用Visual Studio 2012、Entity Framework 5和SQL Server 2008编写一个数据库应用程序。我希望实体框架模拟SQL Server用户(即未登录的用户)。我已经为DB context
MyDatabaseEntities
创建了一个新的构造函数,其中包含一个用于模拟用户名称的参数。以下是我编写的代码:

public partial class MyDatabaseEntities
{
    private String _impersonateUser = null;

    public MyDatabaseEntities(String impersonateUser)
        : base("MyConnectionString")
    {
        _impersonateUser = impersonateUser;

        this.Database.Connection.StateChange += Connection_StateChange;

    }

    void Connection_StateChange(object sender, StateChangeEventArgs e)
    {
        if (e.CurrentState == ConnectionState.Open && e.OriginalState != ConnectionState.Open)
        {
            using (var cmd = this.Database.Connection.CreateCommand())
            {
                cmd.CommandType = CommandType.Text;

                cmd.Parameters.Add(new SqlParameter("user", _impersonateUser));

                cmd.CommandText = "EXECUTE AS USER = @user";

                cmd.ExecuteNonQuery();

            }

        }

    }
我必须加上支票

if (e.CurrentState == ConnectionState.Open && e.OriginalState != ConnectionState.Open)
…因为方法
Connection\u StateChange
方法似乎在状态未更改时也会执行。然后问题是,当我运行代码两次时

public void RunSimpleQuery()
{
    using (MyDatabaseEntities context = new MyDatabaseEntities("UserName"))
    {
        var result = context.TableName.ToList();

    }

}
…实体框架抛出一个
SqlException

当前命令发生严重错误。结果如何 任何,都应丢弃。\r\n当前服务器上发生严重错误 指挥部。如果有结果,则应放弃

有什么想法吗

更新1

我在我的代码上面,我改变了

cmd.CommandText = "EXECUTE AS USER = @user;";
…到

cmd.CommandText = "REVERT; EXECUTE AS USER = @user;";

…我仍然得到相同的
SqlException
错误。

问题是EF在不需要连接时关闭连接并将其返回到池中。因此,当它再次执行某些SQL时,它会从可能未初始化事件的池中请求新连接。但我再次相信,您应该尝试通过手动控制连接生存期来解决这个问题,这样既可以获得连接池的好处,又可以满足您的要求。

我知道这是一个老问题,但可能对某些人有用

我用另一种方式,用你的代码

而不是

连接状态已更改事件

我在同一个类中创建了两个方法:

    public void ChangeUser(String sUser)
    {
        if(Database.Connection.State != ConnectionState.Open)
            Database.Connection.Open();

        using (var cmd = Database.Connection.CreateCommand())
        {
            cmd.CommandType = CommandType.Text;
            cmd.Parameters.Add(new SqlParameter("user", sUser));
            cmd.CommandText = "EXECUTE AS USER = @user;";
            cmd.ExecuteNonQuery();
        }
    }

    public void Revert()
    {
        if (Database.Connection.State != ConnectionState.Open)
            Database.Connection.Open();

        using (var cmd = Database.Connection.CreateCommand())
        {
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "REVERT;";
            cmd.ExecuteNonQuery();
        }
    }
我在执行存储过程之前和之后使用它

using (var db = new MyDatabaseEntities())
        {
            db.ChangeUser(model.Username);
            var result = db.Something();
            db.Revert();
            return result;
        }

它可以与SPs配合使用,即使在多次执行之后也不会抛出异常。如果我能在命令执行后捕捉到一个事件,可能所有事件都会被封装在MyDatabaseEntities上。

问题是EF在不需要时关闭连接,并将其返回到池中。因此,当它再次执行某些SQL时,它会从可能未初始化事件的池中请求新连接。@LadislavMrnka是的,您确定了问题所在。我想我必须在连接字符串中指定不使用连接池…这太可惜了。请为此创建一个答案(只需说出你在评论中所说的),这样我就可以给你评分了。谢谢您应该尝试自己控制连接(通过将其传递给DbContext),但这有一些问题:@LadislavMrnka我将重载MyDatabaseEntities构造函数,并为其提供所需的连接字符串(无需为模拟进行池化)。我将在更新中发布我的代码。同样,请提供答案(复制并粘贴您的评论),这样我就可以给您评分了!=)好问题。你有没有做到这一点,如果有,你能发布一个答案,说明你做了什么吗?再次感谢你的帮助!顺便说一句:我接受你关于手动控制连接生存时间的建议,以获得模拟连接池的好处(你提供的链接非常有用)。我想我会按照你的方式去做。我将更新我的代码并将其作为另一个更新发布。