Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.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# 使用带有OData提要C的存储过程(无实体框架)进行自定义分页_C#_Pagination_Asp.net Web Api2_Odata_Powerbi - Fatal编程技术网

C# 使用带有OData提要C的存储过程(无实体框架)进行自定义分页

C# 使用带有OData提要C的存储过程(无实体框架)进行自定义分页,c#,pagination,asp.net-web-api2,odata,powerbi,C#,Pagination,Asp.net Web Api2,Odata,Powerbi,我想知道是否有人可以帮助我,一段时间以来,我一直在试图弄清楚如何在ODataFeed V4WebAPI 2中实现自定义分页,以便为power bi feed提供服务,但没有成功 数据首先来自一个数据库,即数据库,是使用联接的5个表的组合,这使得它不适合与Entity Framework一起使用,除了在Entity Framework中一个控制器中有45k条记录的速度非常慢之外 我尝试了许多不同的方法,从设置总记录量来欺骗框架,用列表中的空成员填充分页结果,到下面更基本的示例。但是,如果不从控制器

我想知道是否有人可以帮助我,一段时间以来,我一直在试图弄清楚如何在ODataFeed V4WebAPI 2中实现自定义分页,以便为power bi feed提供服务,但没有成功

数据首先来自一个数据库,即数据库,是使用联接的5个表的组合,这使得它不适合与Entity Framework一起使用,除了在Entity Framework中一个控制器中有45k条记录的速度非常慢之外

我尝试了许多不同的方法,从设置总记录量来欺骗框架,用列表中的空成员填充分页结果,到下面更基本的示例。但是,如果不从控制器返回大量记录,我仍然无法获得客户端Power BI正确获取分页结果。请参阅一个简化的查询和代码,任何帮助都是非常受欢迎的,因为似乎没有明确的示例说明如何在不使用实体框架的情况下做到这一点

下面的代码可以工作,但我一直有相同问题的变体框架在返回后对列表进行分页,不管我在返回之前做了什么

T-SQL存储过程:

创建过程[dbo].[GetOrders]@CompanyID int, @跳过整数, @取整数 像 开始 不计数; 挑选* 从命令 其中CompanyID=@CompanyID 按t.OrderID排序 偏移量@跳过行获取下一个@仅获取行 终止 指向调用上述查询的回购协议的控制器

[启用查询] 公共异步任务GetOrdersODataQueryOptions查询选项 { int CompanyID=User.Identity.GetCompanyID.TryParseInt0; ODataQuerySettings设置=新ODataQuerySettings { PageSize=100, }; int OrderCount=\u OrderRepo.GetOrderCountCompanyID; int Skip=0; 如果queryOptions.Skip!=null { Skip=queryOptions.Skip.Value; } IEnumerable results=wait _orderepo.GetAllCompanyID,Skip,100; IQueryable结果=queryOptions.ApplyToresults.AsQueryable,设置; Uri=Request.ODataProperties.NextLink; Request.ODataProperties.TotalCount=OrderCount; PageResult响应=新建PageResult 结果是不可数的, uri,Request.ODataProperties.TotalCount; 返回响应; }
框架的分页在该点返回response;之后完成

在不了解您的全部需求的情况下,我将假设此数据的最终目的地是Power Bi报告。因此,我建议您完全跳过特殊的分页代码,让Power Bi desktop直接连接到SQL Server以访问表

Power Bi desktop将尽最大努力为您重新创建关系。如果您的原始表和ID是以向前的方式命名的,那么Power Bi desktop在为您重新创建关系方面做得相当不错。试试看

导入完成后,您可以在导入时检查关系。如果一个关系是错误的,双击它以删除或编辑

如果您担心每次运行报告都会影响数据库的性能,那么Power Bi的默认模式是导入数据的副本。如果数据小于1GB,建议这样做


对于较大的数据集,可以尝试一个选项。DirectQuery是为了满足加载更大数据集的需要而开发的,它的局限性包括:单一源数据库、无法处理过于复杂的查询、数据库性能以及某些视觉效果在功能上受到限制

我最后找到的解决方案是,假设您关闭过滤等功能并设置最大页面大小,通过扩展EnableQueryAttribute来中断框架。在分页查询中,您需要在页面上方一个位置启动一个内部机制,此解决方案只是一种变通方法。关键是在应用之前将Take设置为0

IEnumerable<Order> results = await _OrderRepo.GetAll(CompanyID, Skip, Take + 1);

您不使用偏移量和提取进行SQL查询有什么原因吗?@MarkC。没有特别的原因,我也可以使用OFFSET和FETCH。出于安全原因,我不能允许Power Bi直接连接到数据库,它不是一个单一的客户端数据库。愚蠢的问题:是否要求您的Power Bi报告翻页查看您的数据集?如果没有,并且您的数据集小于1GB,我仍然建议您在不分页的情况下对ODATA提要使用导入选项。数据集太大,无法以web api2 ODATA paging开箱即用的方式加载,一次获取所有数据,然后对其进行分页,只返回请求的数据量。当一次性处理许多大桌子时,这是非常浪费的。它一次拉取多个表。您是否尝试过在Power BI和自定义函数中使用参数来调用这些参数?
public sealed class PagingAttribute : EnableQueryAttribute
{
    public override IQueryable ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)
    {
        var result = default(IQueryable);
        var originalRequest = queryOptions.Request;

        var skip = queryOptions.Skip == null ? 0 : queryOptions.Skip.Value;
        var take = queryOptions.Top == null ? PageSize : queryOptions.Top.Value;

        queryOptions = ODataQueryOptionsUtilities.Transform(queryOptions, new ODataQueryOptionsUtilitiesTransformSettings { Skip = (map, option) => default(int?) });

        if (queryOptions.Request.ODataProperties().TotalCount != null)
            originalRequest.ODataProperties().TotalCount = originalRequest.GetInlineCount();

        result = queryOptions.ApplyTo(queryable);

        if (skip + take <= originalRequest.ODataProperties().TotalCount)
            originalRequest.ODataProperties().NextLink = NextPageLink.GetNextNewPageLink(originalRequest, (skip + take));

        return result;
    }
}
        originalRequest.ODataProperties().TotalCount = Query.Item1; // Total size of all records to be returned
        originalRequest.SetInlineCount(Query.Item1);