Sto scrivendo un'applicazione di database utilizzando Visual Studio 2012 con Entity Framework 5 e SQL Server 2008. Vorrei che Entity Framework impersonasse un utente di SQL Server (es. accesso). Ho creato un nuovo costruttore per il contesto DB MyDatabaseEntities
che include un argomento per il nome dell'utente da impersonare. Ecco il codice che ho scritto:Entity Framework 5 - Implementazione di SQL Server "Esegui come utente"
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();
}
}
}
ho dovuto aggiungere l'assegno ...
if (e.CurrentState == ConnectionState.Open && e.OriginalState != ConnectionState.Open)
... perché il metodo metodo di Connection_StateChange
sembra per eseguire anche quando lo stato hasn' t cambiato. Poi problema è che quando faccio funzionare il codice due volte,
public void RunSimpleQuery()
{
using (MyDatabaseEntities context = new MyDatabaseEntities("UserName"))
{
var result = context.TableName.ToList();
}
}
... Entity Framework getta un SqlException
:
Un grave errore durante il comando corrente. I risultati, se , devono essere eliminati. \ R \ nSi è verificato un grave errore nel comando corrente . I risultati, se presenti, dovrebbero essere scartati.
Qualche idea?
Aggiornamento 1
ho nel mio codice di cui sopra, ho cambiato ...
cmd.CommandText = "EXECUTE AS USER = @user;";
... al ...
cmd.CommandText = "REVERT; EXECUTE AS USER = @user;";
... e io ancora ottenere lo stesso errore SqlException
.
Il problema è che EF chiude la connessione quando non ne ha bisogno e la restituisce al pool. Quindi, quando esegue nuovamente SQL, richiede una nuova connessione dal pool in cui il tuo evento potrebbe non essere inizializzato. –
@LadislavMrnka Sì, hai identificato il problema. Immagino che dovrò specificare nella stringa di connessione di non usare il pool di connessioni ... è un peccato. Si prega di creare una risposta per questo (basta dire quello che hai detto nel commento) così posso darti il merito. Grazie! – HydroPowerDeveloper
Dovresti provare a prendere il controllo della connessione da te stesso (passando a DbContext) ma c'era qualche problema con questo: http://blogs.msdn.com/b/diego/archive/2012/01/26/exception -da-DbContext-api-EntityConnection-può solo essere-costruito-con-un-chiuso dbconnection.aspx. –