【问题标题】:using CTE in Entity framework for paging在实体框架中使用 CTE 进行分页
【发布时间】:2011-07-06 08:39:29
【问题描述】:

我正在尝试在 sql server 2008 中使用 CTE 并在实体框架中使用它。

以下是SP:

CREATE PROCEDURE GetReportingCategories
    -- Add the parameters for the stored procedure here
    @StartRow INT,
    @EndRow INT,
    @SortDirection VARCHAR(50),
    @SortExpression VARCHAR(50),
    @TotalRecord int OUTPUT
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    ;WITH CTE (CategoryTitle, CreatedDate, UpdatedDate, [Status], RowNumber) AS 
    ( 
        SELECT CategoryTitle, 
            CreatedDate, 
            UpdatedDate, 
            [Status],
            ROW_NUMBER() OVER(ORDER BY
                case when @SortExpression='CategoryTitle' and @SortDirection='DESCENDING' then CategoryTitle end DESC,
                case when @SortExpression='CategoryTitle' and @SortDirection='ASCENDING' then CategoryTitle end ASC) AS RowNumber
        FROM ReportingCategory
    )

    SELECT * INTO #TtCTE FROM CTE;
    SELECT @TotalRecord = ISNULL(SUM(1), 0) FROM #TtCTE;

    SELECT * 
    FROM #TtCTE 
    WHERE RowNumber >= @StartRow AND RowNumber <= @EndRow;
END
GO

SP 完美执行。但是,问题是在 VS2010 中从数据库更新模型后,当我尝试“添加函数导入”时,我没有得到列信息。所以,不能吃。

请指导如何使用实体框架和存储过程实现没有 CTE 的自定义页面。 谢谢。

【问题讨论】:

  • 你为什么用 isnull(sum(1,0)) 而不是 count(*)?
  • @Kyle:我不记得确切,但它是这样的:当 SELECT 语句不返回任何行时,“TotalRecord”也将设置为 0。我知道有很多方法。

标签: visual-studio-2010 sql-server-2008 entity-framework-4 pagination common-table-expression


【解决方案1】:

您无法使用 LINQ 查询实体吗?如果您可以使用 Skip 和 Take 操作可能会更容易解决。

【讨论】:

  • 我被要求使用存储过程。
【解决方案2】:

最后,我得到了它的工作。在数据库中设置以下内容,而不是使用 CTE 或类似的东西:

SET FMTONLY OFF

仅供参考:我没有时间对此声明进行更多调查,但我已经尝试过了,它确实有效。

【讨论】:

  • 每个数据库只能设置一次。
【解决方案3】:

我认为问题在于您使用的是内联临时表——更重要的是,使用 SELECT * INTO 创建它——因此 Entity Framework 无法确定存储过程的输出列将是什么.

这样的事情呢?

CREATE PROCEDURE GetReportingCategories
    -- Add the parameters for the stored procedure here    
    @StartRow INT,
    @EndRow INT,
    @SortDirection VARCHAR(50),
    @SortExpression VARCHAR(50)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    ;WITH CTE (CategoryTitle, CreatedDate, UpdatedDate, [Status], RowNumber) AS
    (
        SELECT CategoryTitle,             
            CreatedDate,
            UpdatedDate,
            [Status],
            ROW_NUMBER() OVER(ORDER BY
                case when @SortExpression='CategoryTitle' and @SortDirection='DESCENDING' then CategoryTitle end DESC,
                case when @SortExpression='CategoryTitle' and @SortDirection='ASCENDING' then CategoryTitle end ASC) AS RowNumber
        FROM ReportingCategory    
    )
    SELECT 
        (SELECT COUNT(*) FROM CTE) AS TotalRecords,
        CategoryTitle,             
        CreatedDate,
        UpdatedDate,
        [Status]
    FROM CTE
    WHERE RowNumber >= @StartRow AND RowNumber <= @EndRow
END

...那么您不需要临时表(或第二个查询),它应该允许实体框架查看输出列。

【讨论】:

  • 在这里,您将 2 个结果集合并为 1 个。这使得查询的可读性和可维护性变得非常低。很多时候,我需要 3-4 个结果集并且非常多样化。但是,我在这里发现的好处是我应该尝试使用显式临时表而不是 SELECT * INTO 的东西。
猜你喜欢
  • 1970-01-01
  • 2020-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 2022-01-01
  • 1970-01-01
相关资源
最近更新 更多