15

The specified cast from a materialized 'System.Guid' type to the 'System.Int32' type is not valid.

InstanceContextMode複数と単一の同時実行モードを持ついくつかのWCFサービスがあります。私たちのアーキテクチャは、コンストラクターベースの依存性注入を使用した緩く結合されたモデルに焦点を当てています。これは、Unity 2.0を使用して実装されます(各サービスのweb.configには、ユニティコンテナーセクションで定義されたインターフェイスとタイプ間のマッピングがあります)。依存関係の1つは、Entity Framework4を使用してMSSqlServerと通信するDALアセンブリ(データアクセスレイヤー)です。データベースとの通信を行うクラスも、ユニティマッピングに含まれています。

統合テストを実行すると、すべてが素晴らしいものになります。ただし、パフォーマンス環境に移動して負荷テスト(2、3、4の同時ユーザー)を実行すると、次のエラーが発生し始めます。

System.InvalidOperationException: The 'auth_token' property on 'Session' could not be set to a 'Int32' value. You must set this property to a non-null value of type 'Guid'.

次のスタックを使用します。

at System.Data.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader`1.GetValue(DbDataReader reader, Int32 ordinal)
at System.Data.Common.Internal.Materialization.Shaper.GetPropertyValueWithErrorHandling[TProperty](Int32 ordinal, String propertyName, String typeName)
at lambda_method(Closure , Shaper )
at System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
at lambda_method(Closure , Shaper )
at System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
at System.Linq.Queryable.First[TSource](IQueryable`1 source)
at MISoa.DataAccessLayer.Authentication.AuthenticationDB.RetrieveSession(Guid authToken)
at MISoa.DataAccessLayer.Authentication.AuthenticationAccess.RetrieveSession(String sessionToken)

犯人の方法は次のとおりです。

public Session RetrieveSession(Guid authToken)
    {
        CheckDBContext();
        var sessions = (from r in _dbContext.Sessions
                where r.auth_token == authToken
                select r);
        return sessions.Count() > 0 ? sessions.First() : null;
    }

CheckDBContextメソッドは、dbコンテキストがnullかどうかをチェックするだけで、nullの場合は、カスタム例外をスローします。

emdx Sessionエンティティオブジェクトには、次のパブリックプロパティがあります。

Guid auth_token
DateTime time_stamp
String user_id
String app_id

したがって、上記のlinqがデータベースから他のオブジェクトを返すことがあるように見えます。最初の列は?intではなくanです。guidもしそうなら-なぜですか?複数のスレッドが互いのdbコンテキストをオーバーライドすることに問題がありますか?ところで-dbコンテキストを別のクラス(BaseDB)にインスタンス化するコードを抽象化しました。このクラスも1で処理されます。つまり、サービスはシングルトンなので、すべての人にBaseDBのインスタンスが1つありますよね?これはここでの問題ですか?

ああ、もう一つ。MSSql 2005があると言われたので、edmxファイルにはProviderManifestToken="2005"。しかし、チェックしたところ、パフォーマンスデータベースを備えたサーバーはバージョン2008です。これは問題ですか?

ご協力ありがとうございました。

4

2 に答える 2

2

複数のスレッドが互いのdbコンテキストをオーバーライドすることに問題がありますか?

はい。ここを参照してください:http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.aspx

上記のリンクの大きな黄色いボックスからの引用:

このObjectContextクラスはスレッドセーフではありません。マルチスレッドシナリオでは、のデータオブジェクトの整合性をObjectContext保証できません。

[ThreadStaticAttribute]あなたは自分の_dbContextフィールドに置くことを検討したいかもしれません。

于 2012-05-17T17:19:21.510 に答える
0

結果がなく、生成されたSQLのどこかでGuidフィールドの比較にnull値== 0が使用されている場合に問題が発生すると思われます。比較を文字列 (両方で .ToString() ) として実行してみて、問題の原因となっているケースをキャッチできるかどうかを確認してください。

于 2012-06-01T12:22:52.323 に答える