3

接続文字列を共有する複数のサブクラスを持つアプリケーションがありDbContextます(これは、単一の大きなDbContext型でのEFの恐ろしい起動時間を回避するためです)。特定の時点で(私にとっては繰り返し可能で、他の人にとっては多少繰り返し可能です)、データベースクエリを作成しようとすると、次のエラーが発生します。

System.Data.EntityException:"基になるプロバイダーがOpenで失敗しました。"
内部例外を除いて:
System.Data.SqlClient.SqlException"ユーザー'username'のログインに失敗しました"

単一の巨人の使用に戻すと、問題は解決したように見えますDbContext

誰かがこれが何を意味するのか/それを修正する方法を知っていますか?(同じ接続文字列を使用するのではなく)同じDbConnectionオブジェクトを再利用した場合に役立ちますか?DbContextsこの接続文字列は、同じリクエストで複数のクエリを実行することにすでに成功しているため、資格情報が不正である可能性はありません。

ASP.NET MVC 3、EF 4.3.1、.NET 4.0、VS2010を使用しています。

関連するスタックトレースは次のとおりです。

 [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()の呼び出しで発生します。

編集:この質問は関連があるかもしれないと思いますが、説明されている競合状態をどうすればよいかわかりません。

編集:問題を理解したので、問題のあるコードを投稿できます:

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

2 に答える 2

7

問題は、PersistSecurityInfo接続文字列プロパティに関連していることが判明しました。MSDNから:

PersistSecurityInfo:接続が開いているか、開いた状態になったことがある場合に、パスワードなどの機密情報が接続の一部として返されないかどうかを示すブール値を取得または設定します。

私の接続文字列には、元々ユーザー名とパスワードが含まれていました。この文字列でDbContextを初期化し、その後、初期コンテキストのDatabase.Connectionプロパティで同じ文字列を使用して別のコンテキストを初期化します。ただし、PersistSecurityInfoがfalseに設定されているため、一部のシナリオでは、パスワードが接続の接続文字列への参照から黙って消え、新しいDbContextインスタンスでのログイン失敗につながりました。

私が考えた解決策は次のとおりです。1。PersistSecurityInfoをtrueに設定します。2。接続文字列への個別の参照を保持し、それを使用します。3.接続にユーザー名とパスワードを入れない別の形式の認証を使用します。ストリング

于 2012-10-01T23:50:15.380 に答える
0

私の知る限り、ユーザーには、db_datareader、db_datawriter、db_ddladmin、db_owner、またはdb_securityadminのロールが必要です。その他の役割情報については、以下を参照してください。

http://msdn.microsoft.com/en-us/library/ms189121(v=SQL.105).aspx

于 2021-12-17T13:09:51.640 に答える