2012-09-28 2 views
3

У меня есть приложение с несколькими подклассами DbContext, которые разделяют строку соединения (это позволяет избежать ужасного времени запуска EF с помощью одного большого типа DbContext). В определенные моменты (повторяемые для меня и несколько для других), я получаю следующее сообщение об ошибке при попытке сделать запрос к базе данных:Ошибка Weird Entity Framework: сбой входа в систему для пользователя

System.Data.EntityException: "The underlying provider failed on Open."
with inner exception:
System.Data.SqlClient.SqlException "Login failed for user 'username'"

Проблема появляется, чтобы уйти, если я переключаюсь обратно с помощью одного гиганта DbContext.

Кто-нибудь знает, что это означает/как его исправить? Помогло бы это, если бы я повторно использовал один и тот же объект DbConnection через DbContexts (в отличие от использования одной и той же строки соединения)? Эта строка соединения уже успела сделать несколько запросов в одном запросе, поэтому не может быть, что учетные данные плохие.

Я использую ASP.NET MVC 3, EF 4.3.1, .NET 4.0, VS 2010.

Соответствующий трассировки стека ниже:

[SqlException (0x80131904): Login failed for user 'testing_net'.] 
    System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +6351920 
    System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +412 
    System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1363 
    System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK) +53 
    System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout) +6366878 
    System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, TimeoutTimer timeout, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance) +6366793 
    System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance) +352 
    System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection) +831 
    System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options) +49 
    System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject) +6368598 
    System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject) +78 
    System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject) +2194 
    System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) +89 
    System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) +6372110 
    System.Data.SqlClient.SqlConnection.Open() +300 
    System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) +67 

[EntityException: The underlying provider failed on Open.] 
    System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure) +11108990 
    System.Data.EntityClient.EntityConnection.Open() +142 
    System.Data.Objects.ObjectContext.EnsureConnection() +97 
    System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) +57 
    System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +47 
    System.Linq.Enumerable.Single(IEnumerable`1 source) +156 

Грубый набросок кода следующим образом:

// db context: 
public class MyDbContext<T> : DbContext { 
    public MyDbContext(string connectionString) : base(connectionString) { } 

    protected override OnModelCreating(DbModelBuilder builder) 
    { 
     // constructs the model base on the type of T 
     // code first POCO entities are annotated with an attribute that links 
     // them to one or more types T 
    } 
} 

Я использую DI AutoFac, чтобы впрыснуть мои DbContext годов в услугах моего уровня доступа к данным. Продолжительность контекста - это длина HttpRequest.

Фактическое исключение возникает при вызове Queryable.Single().

EDIT: думаю, this вопрос может быть уместным, но я не уверен, что делать с состоянием гонки.

EDIT: Теперь, когда я понимаю, этот вопрос, я могу отправить обижая кусок кода:

MyDbContext<T1> db1 = ... 
var connectionString = db1.Database.Connection.ConnectionString; 
var dbContext2 = new MyDbContext<T2>(connectionString); 
+0

Вы используете ASP.Net? –

+1

также вы можете показать код, в котором вы определяете DbContext, а также то, как вы передаете имя пользователя и pw в соединение, если необходимо ..? – MethodMan

+0

@ErikPhilips: да. Я использую ASP.NET MVC 3 – ChaseMedallion

ответ

5

Оказывается, что проблема была связана с строки подключения собственности PersistSecurityInfo. От MSDN:

PersistSecurityInfo: Gets or sets a Boolean value that indicates if security-sensitive information, such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state.

В моей строке подключения изначально было имя пользователя и пароль. Я бы инициализировал DbContext с этой строкой, а затем инициализировал другой контекст, используя ту же строку в свойстве Database.Connection исходного контекста. Однако, поскольку для параметра PersistSecurityInfo установлено значение false, в некоторых сценариях пароль молча исчез из ссылки подключения к строке подключения, что приводит к ошибке входа в новый экземпляр DbContext.

возможных решений, я думал о том, чтобы: 1. Установить PersistSecurityInfo к истинным 2. Держите отдельную ссылку на строку подключения и использование, что 3. Использовать различные формы проверки подлинности, не ставит имя пользователя и пароль в строке подключения

Смежные вопросы