ADO.NET Entity Data Model からの WCF Data Service を用意する
3 つのテーブル
docSVsys: PK ID
,sValue
docSVtext: composite PK sID, fieldID
,mValue
sID has FK relation to docSVsys,ID
fieldID has FK Relation to docFieldDef.ID
docFieldDef PK, ID
,fName
docFieldDef は、fieldID をフィールド名に関連付ける小さな半静的テーブルです。
PK から FK に拡張可能 - これは機能します
http://localhost:64638/WcfDataService1.svc/docSVsys(1)?$expand=docSVtext
この FK から PK に展開できません - これは失敗します。これを機能させることはできますか?
http://localhost:64638/WcfDataService1.svc/docSVtext?$top=1&$expand=docFieldDef
SOは解説用ではありませんが。ODATA と EF は優れたツールです。これは、自動化されたモデルにマッピングされていない大量のデータでした。ODATA を実装するのではなく、いくつかの特定の WCF サービスを追加しました。
.NET コードで TSQL をインターセプトすることはできませんでしたが、SSMS プロファイラーを使用して TSQL をキャプチャすることはできました。これは、有効な (ただし形式が正しくない) クエリのタイムアウトでした。330 万レコードのテーブルから 100 レコードのテーブルへの結合を行い、上位 1 を処理します。330 万のテーブルでは、結合は複合キーの 2 番目の int です。結合は直接ではありません。結合はサブクエリを介して行われます。直接結合とまだ長いクエリにリファクタリングされました (2:30)。並べ替え順序は、PK の 2 番目のコンポーネントで、次に (より大きなテーブルの) 最初のコンポーネントでした。ソート順を最初のコンポーネント、2 番目のコンポーネントに変更すると、クエリは 0 (瞬間) になりました。両方の並べ替え順序には、まだ同じクエリ プランがありました。これも UI を備えたアプリであり、クエリは 1 秒もかからず、すべて手作りの TSQL です。
ODATA インターフェイスが必要だが、クエリの種類を制限し、TSQL を手作りする必要がある。カスタム データ サービス プロバイダーの道をたどって iQueryable を実装することもできますが、それは非常に難しく、クエリの種類を制限するという最初の問題 (愚かなクエリを許可しない) は解決しません。ODATA に準拠するが、クエリの種類を制限する (そして TSQL を作成する) 方法はありますか。このアプリの ODATA の目的は、非常に単純な基準に基づいて大量のボリュームをエクスポートすることです。
面白いこの作品
http://localhost:64638/WcfDataService1.svc/docSVtext(fieldID=101,sID=1)?$expand=docFieldDef
そして、これは機能します(どのFKがPKに戻るか)
http://localhost:64638/WcfDataService1.svc/docSVtext?$top=1&$expand=docSVsys
(this may be a config issue - will review the keys - keys relationships look in order)
The only difference I see it that is where it walks the name of the key was the same in the two tables and where it failed the name of the key changed.
これは機能しますが、このデータをこの順序で見ることは価値がありません
http://localhost:64638/WcfDataService1.svc/docFieldDef?$top=1&$expand=docSVtext
失敗したフィドラー
> # Result Protocol Host URL Body Caching Content-Type Process Comments Custom
> 6 500 HTTP localhost:64638 /WcfDataService1.svc/docSVtext?$top=1&$expand=docFieldDef 250 no-cache
> application/xml iexplore:3188 GET
> /WcfDataService1.svc/docSVtext?$top=1&$expand=docFieldDef HTTP/1.1
> Accept: text/html, application/xhtml+xml, */* Accept-Language: en-us
> User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0;
> Trident/5.0) Accept-Encoding: gzip, deflate Connection: Keep-Alive
> Host: localhost:64638 Cookie:
> ASP.NET_SessionId=l1qpumn5xuopnsyapavocw3a
>
>
> HTTP/1.1 500 Internal Server Error Server: ASP.NET Development
> Server/10.0.0.0 Date: Thu, 28 Jun 2012 23:03:32 GMT X-AspNet-Version:
> 4.0.30319 DataServiceVersion: 1.0; Content-Length: 250 Cache-Control: no-cache Content-Type: application/xml Connection: Close
>
> <?xml version="1.0" encoding="utf-8" standalone="yes"?> <error
> xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
> <code></code> <message xml:lang="en-US">An error occurred while
> processing this request.</message> </error>
MarkStaffo からのリクエストにより、詳細をオンにします。指示:
http://localhost:64638/WcfDataService1.svc/docSVtext?$top=1&$expand=docFieldDef
PK に対して小さなテーブルをヒットする (想定されている) ため、タイムアウトの部分に意味がないことをマークします。
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
-<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <code/> <message xml:lang="en-US">An error occurred while processing this request.</message> -<innererror> <message>An error occurred while executing the command definition. See the inner exception for details.</message> <type>System.Data.EntityCommandExecutionException</type>
<stacktrace> at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues) at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() at System.Data.Services.Providers.BasicExpandProvider.ExpandedQueryable`1.GetEnumerator() at System.Data.Services.Providers.BasicExpandProvider.ExpandedQueryable`1.System.Collections.IEnumerable.GetEnumerator() at System.Data.Services.WebUtil.GetRequestEnumerator(IEnumerable enumerable) at System.Data.Services.DataService`1.SerializeResponseBody(RequestDescription description, IDataService dataService) at System.Data.Services.DataService`1.HandleNonBatchRequest(RequestDescription description) at System.Data.Services.DataService`1.HandleRequest()</stacktrace> -<internalexception> <message>Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.</message> <type>System.Data.SqlClient.SqlException</type> <stacktrace> at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) at System.Data.SqlClient.SqlDataReader.ConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)</stacktrace> </internalexception> </innererror> </error>
画像を別タブで開くとズームできます。