2012-09-28 77 views
3

我有一個應用程序與多個DbContext共享連接字符串(這是爲了避免EF的單一大型DbContext類型的可怕的啓動時間)的子類。奇怪的實體框架錯誤:登錄失敗的用戶

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

這個問題似乎如果我切換回巨單DbContext走開:在某些點(可重複我的,有點替他人),我試圖做一個數據庫查詢時,得到以下錯誤。

有誰知道這意味着什麼/如何解決它?如果我在DbContexts之間重複使用相同的DbConnection對象(與使用相同的連接字符串相反),它會有幫助嗎?這個連接字符串已經成功地在同一個請求中進行了多次查詢,所以它不可能是憑證不好。

我使用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 
    } 
} 

我使用AutoFac的DI將我的DbContext注入服務數據訪問層。上下文的生命週期是HttpRequest的長度。

對Queryable.Single()的調用發生實際異常。

編輯:我認爲this問題可能是相關的,但我不確定如何描述競爭條件。

編輯:現在我明白了這個問題,我可以張貼有問題的代碼:

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

您使用的是ASP.Net嗎? –

+1

也可以顯示你定義DbContext的代碼,以及你如何在必要時將用戶名和密碼傳遞給連接。 – 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爲true 2.保持獨立的參考連接字符串和使用 3.使用不同形式的認證,不把連接字符串中的用戶名和密碼