奇怪的实体框架错误:用户登录失败

Cha*_*ion 3 linq sql-server entity-framework asp.net-mvc-3

我有一个具有多个DbContext子类的应用程序,它们共享一个连接字符串(这是为了避免EF使用单个大型DbContext类型的可怕启动时间).在某些点(对我来说可重复,有些对其他人可重复),在尝试进行数据库查询时出现以下错误:

System.Data.EntityException:"基础提供程序在打开时失败."
内部异常:
System.Data.SqlClient.SqlException"用户'用户名'登录失败'"

如果我切换回使用单个巨人,问题似乎就会消失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
Run Code Online (Sandbox Code Playgroud)

代码的大致轮廓如下:

// 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
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用AutoFac的DI将我的DbContext注入我的数据访问层服务.上下文的生命周期是HttpRequest的长度.

在调用Queryable.Single()时发生实际异常.

编辑:我认为这个问题可能是相关的,但我不确定如何描述所描述的竞争条件.

编辑:既然我理解了这个问题,我可以发布有问题的代码:

MyDbContext<T1> db1 = ...
var connectionString = db1.Database.Connection.ConnectionString; 
var dbContext2 = new MyDbContext<T2>(connectionString);
Run Code Online (Sandbox Code Playgroud)

Cha*_*ion 5

事实证明,该问题与PersistSecurityInfo连接字符串属性有关.来自MSDN:

PersistSecurityInfo:获取或设置一个布尔值,该值指示如果连接处于打开状态或处于打开状态,安全性敏感信息(如密码)是否作为连接的一部分返回.

我的连接字符串最初有一个用户名和密码.我将使用此字符串初始化DbContext,然后使用初始上下文的Database.Connection属性中的相同字符串初始化不同的上下文.但是,由于PersistSecurityInfo设置为false,因此在某些情况下,密码会从连接对连接字符串的引用中无声地消失,从而导致新DbContext实例上的登录失败.

我想到的可能的解决方案是:1.将PersistSecurityInfo设置为true 2.保持对连接字符串的单独引用并使用它3.使用不将用户名和密码放在连接中的其他形式的身份验证串