2016-07-14 3 views
0

私はEntity Framework 6を​​使用しており、クエリの結果をWCFサービスから送信しています。クエリで返されたエンティティを送信しようとすると、動的プロキシが原因で例外が発生します。このためオブジェクトを同じタイプの別のオブジェクトにマップすることは意味がありますか?

私の前の問題を回避するには、

return PatientServiceLogic.GetAll() 
    .Select(p => new Patient { 
    ID = p.ID, 
    FirstName = p.FirstName, 
    Surname = p.Surname, 
    AccidentDate = p.AccidentDate 
    }) 
    .ToList(); 

これは簡単な例です...このようなコードを使用することでした。あなたが想像することができるように、オブジェクトグラフが成長すると、これはむしろ痛いものになります。

私はAutoMapperを発見しました。これは、定型コードをたくさん保存するようです。クライアントアプリケーションのグリッドで使用されるPatientオブジェクトのコレクションを送信したい場合は、完全なPatientオブジェクトグラフが必要ではなく、単純化された平坦化されたバージョンが必要です。そのためには、PatientDtoクラスが問題ありません。

しかし、私はすると完全なオブジェクトグラフを送信したいとします。私はPatientクラスのカーボンコピーを作成すること、そして関連するすべてのクラスを作成して、それらを送信できるように、一方を他方にコピーすることについては何のポイントも見ません。 EFで生成されたクラスを再利用し、Patientオブジェクトを新しいPatientオブジェクトにマップする方が理にかなっています。これは動的プロキシを持たないコードで作成されています。これは基本的に上記の私のコードがやっていることです。

私はこれを試しましたが、私は役に立たない説明できない例外を下に示しました。

誰でもコメントがありますか?これは賢明なことですか?もしそうでなければ、このような状況に対処するにはどうすればよいでしょうか?

は、ここで私はhttp://localhost:5448/PatientsService.svcにHTTPレスポンスを受信中にエラーが発生しましたMapperConfiguration(c => c.CreateMap<Patient, Patient>())

で設定したマッピングを使用してサービスを呼び出すしようとしたとき、私は、WCFテストクライアントからもらった例外です。これは、サービスエンドポイントがHTTPプロトコルを使用しないでバインドしていることが原因である可能性があります。これは、(おそらくサービスのシャットダウンのために)サーバーによって中止されたHTTP要求コンテキストが原因である可能性もあります。詳細はサーバーログを参照してください。

サーバースタックトレース: System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebExceptionで

(WebException webException、HttpWebRequestの要求、HttpAbortReason abortReason)
System.ServiceModel.Channels.HttpChannelFactory`1で。 HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan タイムアウト)で System.ServiceModel.Channels.RequestChannel.Request(メッセージメッセージ、 TimeSpanタイムアウト)で System.ServiceM System.ServiceModel.Channels.ServiceChannel.Call(文字列アクションでodel.Dispatcher.RequestChannelBinder.Requestは(メッセージ メッセージ、のTimeSpanタイムアウト)、 ブール一方向、ProxyOperationRuntime動作は、[]イン、 オブジェクト[]アウト、のTimeSpanタイムアウトオブジェクト) にSystem.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall、ProxyOperationRuntime操作)を に設定します。System.ServiceModel.Channels.ServiceChannelProxy。 System.Runtime.Remoting.Proxies.RealProxyで でSystem.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessageが reqMsg、IMessageがretMsg):(IMessageが メッセージ)[0]に再スロー

例外を呼び出します。

: PatientsServiceClient.GetPatients()

内部例外でPatientsService.GetPatientsでPrivateInvoke(のMessageData & msgData、のInt32型)()

基本接続が閉じられました:受信時に予期しないエラーが発生しました( )。

読み取ることができません: System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpanの タイムアウト)

内部例外でSystem.Net.HttpWebRequest.GetResponse()でトランスポート接続からのデータ:既存の 接続がリモートホストによって強制的に閉じられました。 System.Net.Sockets.NetworkStream.Read(Byte []バッファ、Int32オフセット、 Int32サイズ)、System.Net.PooledStream.Read(Byte []バッファ、Int32 オフセット、Int32サイズ)at System.Net .Connection.SyncRead(HttpWebRequestの要求、ブール userRetrievedStream、ブールprobeRead)

内部例外:

既存の接続を強制的に System.Net.Sockets.Socketのリモートホストによって閉じました。受信(Byte []バッファ、Int32オフセット、Int32 siz System.Net.Sockets.NetworkStream.Read(バイト[]バッファにE、SocketFlags socketFlags)、のInt32)は、あなたの現在の問題は、あなたが作業しfinisheds前に、DB接続が閉じられたことのようです

+0

質問_「レイヤーを通過するときに私たちのエンティティクラスではないデータ転送オブジェクトを使用する理由」_が死んでいると論じられています。あなたの研究は何を示していましたか?質問に答えるか、例外を解決したいですか? – CodeCaster

+0

@CodeCaster実際、私はそれをそのように考えていませんでした。私は、EFで生成されたクラスをPOCO(あなたがコードを見れば、そうであるように見える)として考えていました。私は(おそらく間違って) 'var p = new Patient()'のように)自分で作成すると仮定していましたが、プロキシなしでPOCOを取得します。その観点からは、同じDTOを作成することは無意味に思えました。私が間違って思っているところがわからないので、これを明確にしてください。 –

+0

@CodeCasterコメントはありますか?私はどうしたらいい?誰でもコメントできますか? –

答えて

1

を のInt32のサイズをオフセットあなたのデータで

は、すべての関連するエンティティのためのクエリで

db.mainEntity.Include(i=>i.relatedtable).Include(i=>i.anotherRelatedtable) 

を使用してみてください。

シリアライザであなたのオブジェクトの1対1のコピーを作成するためによくない理由は、ループ(おそらくJSON-feededコンポーネントを使用するときに前にそれらを解決していた)です:

父は子供、子供を持っています子供がいる父親、溢れている父親がいます!

+0

返信いただきありがとうございますが、どのように役立ちますか?関連するすべてのエンティティは既にロードされているので、私は.Include()を使って何を追加するのか分かりません。私の根底にある問題(これは私がこの質問で取り組んでいたものではない)は、接続が閉じられるまで関連するエンティティがロードされていないということです。それを避けるために、関連するエンティティ**に**を含めるのではなく、クエリを伝える必要があります。どうぞご理解ください。 –

+0

eager loadingが有効な場合。エンティティは、参照されるときにのみ、関連要素をロードします。私はそれを試しましたが、あなたのオブジェクトがメモリ内にある場合は、EFがアクセスしようとする前に子要素を割り当てるかどうかわかりません。 「インクルード」を使用すると、クエリを実行するときにそれらの関係を更新する必要があります。もちろん、**接続が閉じる前に結果を尋ねる必要があります**ので、コンテキストのusingステートメントまたはスコープを終了する前に、結果セットでToList()を試してください –

関連する問題