Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么实体框架为Azure Mobile Services表控制器生成以下嵌套SQL_C#_Entity Framework_Asp.net Web Api2_Odata_Azure Mobile Services - Fatal编程技术网

C# 为什么实体框架为Azure Mobile Services表控制器生成以下嵌套SQL

C# 为什么实体框架为Azure Mobile Services表控制器生成以下嵌套SQL,c#,entity-framework,asp.net-web-api2,odata,azure-mobile-services,C#,Entity Framework,Asp.net Web Api2,Odata,Azure Mobile Services,当我将实体框架与TableController一起使用时,我试图弄清实体框架问题的根源 我创建了以下设置 基本的TodoItem示例附带了一个新的移动Web API,它利用EntityFramework、TableController和默认的EntityDomainManager public class TodoItemController : TableController<TodoItem> { protected override void Initialize(Ht

当我将实体框架与
TableController一起使用时,我试图弄清实体框架问题的根源

我创建了以下设置

  • 基本的TodoItem示例附带了一个新的移动Web 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;
        }
    

    但是对于TabelLogFror,你可以得到下面的一块SQL,中间有一个*Fix*GuID,结果是嵌套的SQL语句。当您开始处理任何ODATAv3查询(如$top、$skip、$filter和$expand)时,它的性能将完全变成垃圾

    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
    
    您可以在此处看到这两个查询的结果

    因此,我的问题是:

    • 为什么
      TableController
      会以这种方式生成SQL

    • < L> > P>在查询中间的*Fux*GUID是什么?(在我停止并重新启动应用程序之前,它将保持不变,因此我不知道它是会话、客户端还是数据库上下文特定的)

    • TableController在管道中的什么位置对
      IQueryable
      进行这些修改?我假设在调用
      Query()
      方法之后,它是通过某个中间件步骤或稍后在请求中执行的属性完成的,但我一生都找不到它


    您的一个表正在后端和客户端之间同步,因为如果这是您的第二个sql

    请在此处阅读更多信息:

    根据您的描述,我做了一些研究,发现Azure Mobile Server SDK使用下面的代码行为相同的操作添加额外的查询相关筛选器,并启用控制器操作以支持OData查询参数

    controllerSettings.Services.Add(typeof(IFilterProvider), new TableFilterProvider());
    
    注意:附加筛选器将在您的操作执行后执行,并返回
    IQueryable

    您可以检查并发现,
    OnActionExecuted
    将调用
    ExecuteQuery
    方法,并最终调用对给定的
    IQueryable
    应用OData查询选项($filter、$orderby、$top、$skip和$inlinecount等)

    据我所知,嵌套SQL语句是由OData组件生成的。调用
    ODataQueryOptions.ApplyTo
    后,您的IQueryable已被修改,相关的sql语句也已被修改。我在我的常规Web API控制器中进行了如下测试,您可以参考它:

    请求:

    Get http://localhost:58971/api/todoitem?$top=2&$select=Text,Id,Version
    
    在应用OData查询选项之前:

    Get http://localhost:58971/api/todoitem?$top=2&$select=Text,Id,Version
    

    应用OData查询选项后:

    Get http://localhost:58971/api/todoitem?$top=2&$select=Text,Id,Version
    

    我想这与实现Odata查询的移动服务器SDK有关。我发现如果我们使用var items=Query().ToList(),sql查询与web api一样正确。但是我们不能使用Odata查询,但这不是一个真正的选项,因为客户端消费者将依赖于使用Odata$vars。e、 g.在初始加载时,它将通过API调用使用
    $top
    $skip
    对apge执行初始数据库同步。这是因为EntityDomainManager下载并保留字段值以及每行以进行并发检查。Guid是源代码中的ETAG类型您使用的是什么类型的数据库?