我试图用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 –