Azureのモバイルサービス表コントローラの次のネストされたSQLを生成するEntity Frameworkのです。は、なぜ私は次のセットアップを作成しました<code>TableController</code></p> <p>でそれを使用した場合、エンティティフレームワークの問題の底に取得しようとしている
EntityFramework、TableController &デフォルトEntityDomainManager
public class TodoItemController : TableController<TodoItem> { protected override void Initialize(HttpControllerContext controllerContext) { base.Initialize(controllerContext); context = new MobileServiceContext(); context.Database.Log += LogToDebug; DomainManager = new EntityDomainManager<TodoItem>(context, Request); } public IQueryable<TodoItem> GetAllTodoItems() { var q = Query(); return q; }
バニラウェブAPI 2コントローラを活用し、新たなモバイルWeb APIを備えた基本的なTodoItem例。私はちょうど
にIQueryable
Where(_ => !_.IsDeleted)
変更で追加するDomainManager
経由でコールをプロキシさQuery
方法、掘り下げる、細かい歯の櫛でtablecontroller
コードを行ってきたpublic class TodoItemsWebController : ApiController { private MobileServiceContext db = new MobileServiceContext(); public TodoItemsWebController() { db.Database.Log += LogToDebug; } public IQueryable<TodoItem> GetTodoItems() { return db.TodoItems; }
しかし、2つのクエリは非常に異なるSQLを生成します。
通常のWeb APIコントローラでは、次のSQLを取得します。
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Version] AS [Version],
[Extent1].[CreatedAt] AS [CreatedAt],
[Extent1].[UpdatedAt] AS [UpdatedAt],
[Extent1].[Deleted] AS [Deleted],
[Extent1].[Text] AS [Text],
[Extent1].[Complete] AS [Complete]
FROM [dbo].[TodoItems] AS [Extent1]
しかしTableControllerについては、次のそれの真ん中に*マジック* GUIDを持つSQLのチャンク、およびネストされたSQL文で結果を取得します。 $ top、$ skip、$ filter、$ expandのようなODATAv3クエリのいずれかを扱うときに、この処理が完了するとゴミが出ます。
SELECT TOP (51)
[Project1].[C1] AS [C1],
[Project1].[C2] AS [C2],
[Project1].[C3] AS [C3],
[Project1].[Complete] AS [Complete],
[Project1].[C4] AS [C4],
[Project1].[Text] AS [Text],
[Project1].[C5] AS [C5],
[Project1].[Deleted] AS [Deleted],
[Project1].[C6] AS [C6],
[Project1].[UpdatedAt] AS [UpdatedAt],
[Project1].[C7] AS [C7],
[Project1].[CreatedAt] AS [CreatedAt],
[Project1].[C8] AS [C8],
[Project1].[Version] AS [Version],
[Project1].[C9] AS [C9],
[Project1].[Id] AS [Id]
FROM (SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Version] AS [Version],
[Extent1].[CreatedAt] AS [CreatedAt],
[Extent1].[UpdatedAt] AS [UpdatedAt],
[Extent1].[Deleted] AS [Deleted],
[Extent1].[Text] AS [Text],
[Extent1].[Complete] AS [Complete],
1 AS [C1],
N'804f84c6-7576-488a-af10-d7a6402da3bb' AS [C2],
N'Complete' AS [C3],
N'Text' AS [C4],
N'Deleted' AS [C5],
N'UpdatedAt' AS [C6],
N'CreatedAt' AS [C7],
N'Version' AS [C8],
N'Id' AS [C9]
FROM [dbo].[TodoItems] AS [Extent1]
) AS [Project1]
ORDER BY [Project1].[Id] ASC
ここでは両方のクエリの結果を確認できます。 https://pastebin.com/tSACq6eg
は、だから私の質問は以下のとおりです。
はなぜ
TableController
は、このようにSQLを生成していますか?クエリの途中で* magic * guidとは何ですか? (アプリケーションを停止して再起動してセッションやクライアント、DBのコンテキストがわからないので、アプリケーションを停止して再起動するまでは同じままです)
Query()
メソッドが呼び出された後に、要求の後半でミドルウェアのステップまたは実行された属性によって実行されたと見なしますが、私の人生にとってはそれを見つけることができません。
これは、Odataクエリを実装するモバイルサーバーSDKに関連していると思います。私がvar items = Query()。ToList()を使用すると、SQLクエリがWeb APIのように正しいことがわかりました。しかし、我々はOdataクエリを使用することができませんでした。 –
これは本当にオプションではありませんが、クライアントコンシューマはOdata $ varsの使用に依存するためです。例えば初期ロード時には '$ top'と' $ skip'を使用して、APIの呼び出しを行い、最初のDB Syncを実行します。 –
これは、EntityDomainManagerが並行性チェックのために各行と共にフィールドの値をダウンロードして保持するためです。 GuidはソースからのETAGの一種ですhttps://github.com/Azure/azure-mobile-apps-net-server/blob/master/src/Microsoft.Azure.Mobile.Server.Entity/EntityDomainManager.cs –