2012-05-10 21 views
14

The specified cast from a materialized 'System.Guid' type to the 'System.Int32' type is not valid.「可能System.Int32」タイプが有効でない

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

統合テストを実行するとすべてが素晴らしいです。しかし、我々は、我々は次のエラー見始める負荷テスト(2、3、4同時ユーザ)を実行するために私たちのパフォーマンス環境に移行する場合:ここで

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) 

:以下スタックと

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'.

を犯人の方法である:

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方法は、単純にそれがあるならば、それはカスタムEXCEPをスローし、デシベルコンテキストがnullであるかどうかをチェックし、 。時々、上記のLINQは、最初の列はintない​​あるデータベースから、いくつかの他のオブジェクトを返すように

Guid auth_token 
DateTime time_stamp 
String user_id 
String app_id 

だから、それが見えます:

emdxセッションエンティティ・オブジェクトは、これらのパブリックプロパティを持っていますか?もしそうなら - なぜ?お互いのdbコンテキストをオーバーライドする複数のスレッドに問題がありますか? BTW - dbコンテキストをインスタンス化するコードを抽象化して、別個のクラス(BaseDB)にしました。これも1で処理されます。だから、サービスはシングルトンなので、皆のために1つのBaseDBインスタンスを持っていますよね?これはここの問題ですか?

もう、もう1つ。私たちはMSSql 2005を持っていると言われましたので、edmxファイルにはProviderManifestToken="2005"があります。しかし、私はちょうど確認し、私たちのパフォーマンスデータベースを持つサーバーはバージョン2008です。これは問題ですか?

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

+0

私が確認する最初の簡単なこと:auth_tokenはあなたのデータベースのGuidですか?エラーは何かがsession.auth_tokenをintに設定しようとしていることを示しています。正しくマップされていないint ID列はありますか?SQLプロファイリングトレースを行い、実際に行われたSQL呼び出しを識別できますか?私は本当にここであなたの問題を引き起こしているマルチスレッドを疑う。 –

+0

データベース内の列が対応するプロパティタイプであることを確認してください。例外は、DbDataReaderはGuidを読み込みますが、クラスのプロパティはintであると言います。 – Pawel

答えて

2

Do I have a problem with multiple threads overriding each other's db context?

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

見積もりを上記のリンクで大きな黄色のボックスから:

The ObjectContext class is not thread safe. The integrity of data objects in an ObjectContext cannot be ensured in multithreaded scenarios.

あなたの_dbContextフィールド上[ThreadStaticAttribute]を置くことを検討する必要があります。

+1

主な問題は、ObjectContextがThreadsafeではないことです。これは大丈夫ですが、DbContextプロパティを作成すると、HoststaticとWCF/Asp.NetでThreadstaticを使用すると、より多くの問題が発生する可能性があります。 )プロパティを初期化します。たとえば、WCFを使用する場合は、要求を受け入れるスレッドがそれを実行しているスレッドと異なる場合があるため、OperationContextを使用してこれらのものを格納する必要があります。 [operationcontext](http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontext.aspx)を参照してください。 –

+0

@Bernhard Kircher:かなり右 - 良い点! – RobSiklos

0

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