我試圖用TableController
爲什麼實體框架生成Azure的移動服務表控制器
我創建了以下設置使用時才能到實體框架問題的底部以下嵌套的SQL。
提供一個新的移動網絡API它利用的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控制器的基本的TodoItem例子。
public class TodoItemsWebController : ApiController { private MobileServiceContext db = new MobileServiceContext(); public TodoItemsWebController() { db.Database.Log += LogToDebug; } public IQueryable<TodoItem> GetTodoItems() { return db.TodoItems; }
我已經通過tablecontroller
代碼用細齒梳去,挖到Query
方法,它只是進行代理通過DomainManager
調用在Where(_ => !_.IsDeleted)
修改添加到IQueryable
然而,這兩個查詢產生了非常不同的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,你得到的SQL以下塊具有*魔法*的Guid在它的中間,並導致一個嵌套的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上下文)
確切位置在哪裏的管道是使這些修改到
IQueryable
的TableController?我假定在調用Query()
方法之後,它通過一些中間件步驟或稍後在請求中執行的屬性完成,但我不能在我的生活中找到它。
我想這與移動服務器SDK實現Odata查詢有關。我發現如果我們使用var items = Query()。ToList(),sql查詢就像web api一樣。但我們無法使用Odata查詢。 –
這並不是一個真正的選擇,因爲客戶的消費者會依賴Odata $ vars。例如在初始加載時,它將使用'$ top'&'$ skip'通過API調用來執行初始數據庫同步。 –
這是因爲EntityDomainManager會爲每個行下載並保留字段值以進行併發檢查。而Guid是一種來自https://github.com/Azure/azure-mobile-apps-net-server/blob/master/src/Microsoft.Azure.Mobile.Server.Entity/EntityDomainManager.cs的ETAG –