Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.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# 如何在亚音速2.2中执行Oracle top-n(分页)查询?_C#_Oracle_Subsonic_Pagination_Subsonic2.2 - Fatal编程技术网

C# 如何在亚音速2.2中执行Oracle top-n(分页)查询?

C# 如何在亚音速2.2中执行Oracle top-n(分页)查询?,c#,oracle,subsonic,pagination,subsonic2.2,C#,Oracle,Subsonic,Pagination,Subsonic2.2,免责声明:出于安全原因,我更改/混淆了此处的一些变量/表/列名。如果有点不对劲,请原谅我 我正在构建Oracle 10g数据库的前端,并尝试获取分页数据。除了分页,下面的亚音速2.2代码按照我想要的顺序提供了我想要的: var q = new Select() .From(AppDb.MyTable.Schema) .Where(AppDb.MyTable.DisabledDateColumn).IsNull() .OrderDesc(AppDb.MyTable.CreatedDat

免责声明:出于安全原因,我更改/混淆了此处的一些变量/表/列名。如果有点不对劲,请原谅我

我正在构建Oracle 10g数据库的前端,并尝试获取分页数据。除了分页,下面的亚音速2.2代码按照我想要的顺序提供了我想要的:

var q = new Select()
  .From(AppDb.MyTable.Schema)
  .Where(AppDb.MyTable.DisabledDateColumn).IsNull()
  .OrderDesc(AppDb.MyTable.CreatedDateColumn.ColumnName)

System.Console.Out.Writeline(q.BuildStatement());
这将生成以下SQL:

SELECT
    MYSCHEMA.MYTABLE.ID,
    MYSCHEMA.MYTABLE.DISABLED_DATE
FROM
    MYSCHEMA.MYTABLE
WHERE
    MYSCHEMA.MYTABLE.DISABLED_DATE IS NULL
ORDER BY
    CREATED_DATE DESC
然后我尝试介绍分页:

var q = new Select()
  .From(AppDb.MyTable.Schema)
  .Where(AppDb.MyTable.DisabledDateColumn).IsNull()
  .OrderDesc(AppDb.MyTable.CreatedDateColumn.ColumnName)
  .Paged(0, 10);
它删除了我的WHERE和ORDER BY条款:

SELECT * FROM (
    SELECT
        MYSCHEMA.MYTABLE.ID,
        MYSCHEMA.MYTABLE.DISABLED_DATE,
        ROWNUM as row_number
    FROM
        MYSCHEMA.MYTABLE
)
WHERE
    row_number BETWEEN 1 AND 10
我是亚音速的新手,所以我不知道这是否是一个bug,或者我只是没有按照首选的方式来做,或者Oracle是否要求以一种不同的、更以Oracle为中心的方式来做。甲骨文似乎对一切都有这样的要求


如果不明显的话,我想要的是每个后续页面包含10条最近创建的非禁用记录。如何在亚音速2.2中做到这一点?

如果内部SQL包含第一条语句,包括where和order by,则Oracle可以使用Top-N查询

所以,我要说的是,没有甲骨文明确的理由省略它们

从未使用过亚音速,不知道你是否需要在那里做不同的事情


就性能而言,禁用日期、创建日期的索引应该可以实现如下功能:。

如果内部SQL包含第一条语句,包括where和order by,则Oracle可以使用Top-N查询

所以,我要说的是,没有甲骨文明确的理由省略它们

从未使用过亚音速,不知道你是否需要在那里做不同的事情


就性能而言,禁用日期、创建日期的索引应该起到如下作用:。

看起来您的查询生成的SQL与当前查询生成的SQL不一样。以下是从第852行开始的相关代码:

    if(qry.PageIndex < 0)
        query = String.Format("{0} {1} FROM {2}.{3} {4} {5}",select ,columns, table.SchemaName, table.Name, where, order);
    else
    {
        int start = qry.PageIndex * qry.PageSize;
        int end = (qry.PageIndex + 1) * qry.PageSize;

        const string cteFormat =
                    "WITH pagedtable AS (SELECT {0}, ROW_NUMBER () OVER ({1}) AS rowindex FROM {2}.{3} {4}) SELECT {5}, rowindex FROM pagedtable WHERE rowindex >= {6} AND rowindex < {7} ORDER BY rowindex";
        query = string.Format(cteFormat, columns, order,table.SchemaName, table.Name, where, columns.Replace(table.Name + ".", String.Empty), start, end);
    }
    return query;

也许对当前源代码进行更新就可以做到这一点。如果实际的提供程序有问题,您可以将其与SqlDataProvider进行比较,以获得可能存在问题的提示。

看起来您的查询生成的SQL与当前应生成的SQL不一样。以下是从第852行开始的相关代码:

    if(qry.PageIndex < 0)
        query = String.Format("{0} {1} FROM {2}.{3} {4} {5}",select ,columns, table.SchemaName, table.Name, where, order);
    else
    {
        int start = qry.PageIndex * qry.PageSize;
        int end = (qry.PageIndex + 1) * qry.PageSize;

        const string cteFormat =
                    "WITH pagedtable AS (SELECT {0}, ROW_NUMBER () OVER ({1}) AS rowindex FROM {2}.{3} {4}) SELECT {5}, rowindex FROM pagedtable WHERE rowindex >= {6} AND rowindex < {7} ORDER BY rowindex";
        query = string.Format(cteFormat, columns, order,table.SchemaName, table.Name, where, columns.Replace(table.Name + ".", String.Empty), start, end);
    }
    return query;

也许对当前源代码进行更新就可以做到这一点。如果实际的提供程序有问题,您可以将其与SqlDataProvider进行比较,以了解可能存在的问题。

我在使用NET 2.0和Oracle 9i R2的环境中,遇到了相同的问题。我用的是亚音速2.2

我从GitHub下载了源代码,我发现:

@ranomore OracleDataProvider.GetSelectSql引用的代码仅在使用SubSonic.Query对象时调用。由于OP和我自己使用的Select对象是从更新且功能更强大的SubSonic.SqlQuery对象派生的,因此永远不会调用OracleDataProvider.GetSelectSql。取而代之的是,调用并生成OP发布的SQL。这段代码有缺陷,因为它从未将WHERE和ORDER by子句添加到它最终生成的分页查询中

我将BuildPagedSelectStatement的内容替换为基于AnisqlGenerator.BuildSelectStatement的内容:

public override string BuildPagedSelectStatement()
{
    int startnum = query.PageSize * query.CurrentPage + 1;
    int endnum = query.PageSize * query.CurrentPage + query.PageSize;
    string orderBy = String.Empty;

    if (this.query.OrderBys.Count > 0)
        orderBy = GenerateOrderBy();

    //The ROW_NUMBER() function in Oracle requires an ORDER BY clause.
    //In case one is not specified, we need to halt and inform the caller.
    if(orderBy.Equals(String.Empty))
        throw new ArgumentException("There is no column specified for the ORDER BY clause", "OrderBys");

    System.Text.StringBuilder sql = new System.Text.StringBuilder();

    //Build the command string
    sql.Append("WITH pagedtable AS (");
    sql.Append(GenerateCommandLine());

    //Since this class is for Oracle-specific SQL, we can add a hint
    //which should help pagination queries return rows more quickly.
    //AFAIK, this is only valid for Oracle 9i or newer.
    sql.Replace("SELECT", "SELECT /*+ first_rows('" + query.PageSize + "') */");

    sql.Append(", ROW_NUMBER () OVER (");
    sql.Append(orderBy);
    sql.Append(") AS rowindex ");
    sql.Append(Environment.NewLine);
    sql.Append(GenerateFromList());
    sql.Append(GenerateJoins());

    sql.Append(GenerateWhere());

    if (query.Aggregates.Count > 0)
    {
        sql.Append(GenerateGroupBy());
        sql.Append(Environment.NewLine);
        sql.Append(GenerateHaving());
    }

    sql.Append(") SELECT * FROM pagedtable WHERE rowindex >= ");
    sql.Append(startnum);
    sql.Append(" AND rowindex < ");
    sql.Append(endnum);
    sql.Append(" ORDER BY rowindex");

    return sql.ToString();
}

以上这些对我很有用。希望这能帮助别人

我在一个使用Net2.0和Oracle 9i R2的环境中,遇到了同样的问题。我用的是亚音速2.2

我从GitHub下载了源代码,我发现:

@ranomore OracleDataProvider.GetSelectSql引用的代码仅在使用SubSonic.Query对象时调用。由于OP和我自己使用的Select对象是从更新且功能更强大的SubSonic.SqlQuery对象派生的,因此永远不会调用OracleDataProvider.GetSelectSql。取而代之的是,调用并生成OP发布的SQL。这段代码有缺陷,因为它从未将WHERE和ORDER by子句添加到它最终生成的分页查询中

我将BuildPagedSelectStatement的内容替换为基于AnisqlGenerator.BuildSelectStatement的内容:

public override string BuildPagedSelectStatement()
{
    int startnum = query.PageSize * query.CurrentPage + 1;
    int endnum = query.PageSize * query.CurrentPage + query.PageSize;
    string orderBy = String.Empty;

    if (this.query.OrderBys.Count > 0)
        orderBy = GenerateOrderBy();

    //The ROW_NUMBER() function in Oracle requires an ORDER BY clause.
    //In case one is not specified, we need to halt and inform the caller.
    if(orderBy.Equals(String.Empty))
        throw new ArgumentException("There is no column specified for the ORDER BY clause", "OrderBys");

    System.Text.StringBuilder sql = new System.Text.StringBuilder();

    //Build the command string
    sql.Append("WITH pagedtable AS (");
    sql.Append(GenerateCommandLine());

    //Since this class is for Oracle-specific SQL, we can add a hint
    //which should help pagination queries return rows more quickly.
    //AFAIK, this is only valid for Oracle 9i or newer.
    sql.Replace("SELECT", "SELECT /*+ first_rows('" + query.PageSize + "') */");

    sql.Append(", ROW_NUMBER () OVER (");
    sql.Append(orderBy);
    sql.Append(") AS rowindex ");
    sql.Append(Environment.NewLine);
    sql.Append(GenerateFromList());
    sql.Append(GenerateJoins());

    sql.Append(GenerateWhere());

    if (query.Aggregates.Count > 0)
    {
        sql.Append(GenerateGroupBy());
        sql.Append(Environment.NewLine);
        sql.Append(GenerateHaving());
    }

    sql.Append(") SELECT * FROM pagedtable WHERE rowindex >= ");
    sql.Append(startnum);
    sql.Append(" AND rowindex < ");
    sql.Append(endnum);
    sql.Append(" ORDER BY rowindex");

    return sql.ToString();
}
以上这些对我很有用。希望这能帮助别人