Piszę aplikację bazy danych przy użyciu Visual Studio 2012 z Entity Framework 5 i SQL Server 2008. Chciałbym Entity Framework podszywać się pod użytkownika SQL Server (tj. Zaloguj Się). Stworzyłem nowy konstruktor dla kontekstu DB MyDatabaseEntities
, który zawiera argument nazwy użytkownika do podszywania się. Oto kod, który pisałem:Entity Framework 5 - Implementacja SQL Server "Execute As User"
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();
}
}
}
musiałem dodać czek ...
if (e.CurrentState == ConnectionState.Open && e.OriginalState != ConnectionState.Open)
... ponieważ metoda metoda Connection_StateChange
wydaje się wykonać nawet gdy stan hasn” t zmienił się. Wtedy problemem jest to, że gdy uruchamiam kod dwukrotnie,
public void RunSimpleQuery()
{
using (MyDatabaseEntities context = new MyDatabaseEntities("UserName"))
{
var result = context.TableName.ToList();
}
}
... Entity Framework rzuca SqlException
:
poważny błąd wystąpił na bieżącej komendy. Wyniki, jeśli jakiekolwiek, powinny zostać odrzucone. \ R \ nW przypadku bieżącego polecenia wystąpił poważny błąd. Wyniki, jeśli występują, należy odrzucić.
Wszelkie pomysły?
Aktualizacja 1
ja w moim kodu powyżej, zmieniłem ...
cmd.CommandText = "EXECUTE AS USER = @user;";
... do ...
cmd.CommandText = "REVERT; EXECUTE AS USER = @user;";
... a ja wciąż uzyskać ten sam błąd SqlException
.
Problem polega na tym, że EF zamyka połączenie, gdy nie jest potrzebne, i zwraca je z powrotem do puli. Więc kiedy ponownie wykona jakiś SQL, żąda nowego połączenia z puli, gdzie twoje zdarzenie może nie zostać zainicjalizowane. –
@LadislavMrnka Tak, zidentyfikowałeś problem. Sądzę, że będę musiał określić w łańcuchu połączenia, aby nie używać łączenia połączeń ... to wstyd. Utwórz odpowiedź na to (powiedz to, co powiedziałeś w komentarzu), aby dać ci kredyt. Dzięki! – HydroPowerDeveloper
Powinieneś raczej spróbować przejąć kontrolę nad samym połączeniem (przekazując go do DbContext), ale wystąpił problem z tym: http://blogs.msdn.com/b/diego/archive/2012/01/26/exception -z-dbcontext-api-uprawnienia-połączenie-może-być-skonstruowane-z-zamkniętym-dbconnection.aspx. –