visual-studio-2012 sql-server-2008-r2 entity-framework-5 impersonation

visual studio 2012 - Entity Framework 5-Implementación de SQL Server "Ejecutar como usuario"



visual-studio-2012 sql-server-2008-r2 (2)

El problema es que EF cierra la conexión cuando no la necesita y la devuelve al grupo. Entonces, cuando ejecuta SQL otra vez, solicita una nueva conexión desde el grupo donde su evento no puede ser inicializado. Pero nuevamente, creo que debe intentar resolver esto controlando manualmente el tiempo de vida de la conexión para que ambos se beneficien de la agrupación de conexiones y puedan cumplir con sus requisitos.

Estoy escribiendo una aplicación de base de datos con Visual Studio 2012 con Entity Framework 5 y SQL Server 2008. Me gustaría que Entity Framework se haga pasar por un usuario de SQL Server (es decir, un usuario sin un inicio de sesión). He creado un nuevo constructor para el contexto de base de datos MyDatabaseEntities que incluye un argumento para el nombre del usuario para suplantar. Aquí está el código que he escrito:

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(); } } }

Tuve que agregar el cheque ...

if (e.CurrentState == ConnectionState.Open && e.OriginalState != ConnectionState.Open)

... porque el método Connection_StateChange método parece ejecutarse incluso cuando el estado no ha cambiado. Entonces el problema es que cuando ejecuto el código dos veces ,

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

... Entity Framework arroja una SqlException :

Se produjo un error grave en el comando actual. Los resultados, si los hay, deben descartarse. / R / nUn error grave ocurrió en el comando actual. Los resultados, si los hay, deben descartarse.

¿Algunas ideas?

Actualización 1

Yo en mi código anterior, cambié ...

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

...a...

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

... y sigo teniendo el mismo error SqlException .


Sé que es una vieja pregunta, pero tal vez sea útil para alguien.

Lo hice de otra manera, usando tu código ...

En lugar de

Evento Connection_StateChanged

Creo dos métodos en la misma clase:

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(); } }

Lo uso antes y después de ejecutar el procedimiento almacenado,

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

Funciona bien con SP y no arroja una excepción incluso después de muchas ejecuciones. Si pudiera detectar un evento después de la ejecución del comando, quizás todo esté encapsulado en MyDatabaseEntities.