【问题标题】:LINQ - Dynamic OrderBy in VB.NetLINQ - VB.Net 中的动态 OrderBy
【发布时间】:2009-05-27 19:25:35
【问题描述】:

我正在尝试执行与从 Phil Haack 到 VB 的示例代码类似的操作,而 LINQ Orderby 给我带来了问题 - 我不知道该怎么做。为完整性发布了整个方法。

这是 C# 版本:

    public ActionResult DynamicGridData(string sidx, string sord, int page, int rows)
    {
        var context = new HaackOverflowDataContext();
        int pageIndex = Convert.ToInt32(page) - 1;
        int pageSize = rows;
        int totalRecords = context.Questions.Count();
        int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);

        var questions = context.Questions.OrderBy(sidx + " " + sord).Skip(pageIndex * pageSize).Take(pageSize);

        var jsonData = new
        {
            total = totalPages,
            page = page,
            records = totalRecords,
            rows = (
                from question in questions
                select new
                {
                    i = question.Id,
                    cell = new string[] { question.Id.ToString(), question.Votes.ToString(), question.Title }
                }).ToArray()
        };
        return Json(jsonData);
    }

我的问题在于这条线...:

var questions = context.Questions.OrderBy(sidx + " " + sord).Skip(pageIndex * pageSize).Take(pageSize);

在 VB.Net 中 OrderBy 不接受字符串作为值 - 它似乎在 C# 中这样做(或者我遗漏了一些东西)。

(请不要使用 VAR 不是这里的问题,我已经涵盖了。:))

编辑: 这是我得到的错误(我根本无法编译):

重载解析失败,因为无法使用这些参数调用可访问的“OrderBy”...

完整错误消息的屏幕截图:

编辑2:

根据要求提供更多信息。 sidx 包含要排序的列的名称 sord 包含 asc 或 desc

VB 代码:

Function MemberData(ByVal sidx As String, ByVal sord As String, ByVal page As Integer, ByVal rows As Integer) As JsonResult

    Dim allRecords As IQueryable(Of Models.Member) = Me.MemberRepository.FindAllMembers
    Dim currentPageRecords As IQueryable(Of Models.Member)
    Dim pageIndex As Integer = page - 1
    Dim pageSize As Integer = rows
    Dim totalRecords As Integer = allRecords.Count
    Dim totalPages As Integer = CInt(Math.Ceiling(totalRecords / pageSize))

    Dim orderBy As String = sidx + " " + sord

    currentPageRecords = allRecords.OrderBy(Function(m) orderBy).Skip(pageIndex * pageSize).Take(pageSize)

    Dim jsonData = New With { _
          .total = totalPages, _
          .page = page, _
          .records = totalRecords, _
          .rows = New ArrayList _
        }

    For Each member As Models.Member In currentPageRecords
        jsonData.rows.Add(New With {.id = member.MemberId, .cell = GenerateCellData(member)})
    Next

    Return Json(jsonData)

End Function

【问题讨论】:

  • 您看到的错误是什么?
  • 刚刚在原始问题中添加了更多信息。 :)
  • 字符串 sidx 和 sord 包含什么?
  • 您能否也发布包含错误的 VB 代码?
  • Dennis Palmer>> 添加了 vb 代码和更多信息。 :)

标签: c# .net vb.net linq


【解决方案1】:

他是否有可能使用Dynamic Linq? 使用动态 linq,您可以将字符串传递给 OrderBy 方法以及许多其他 IEnumerable 扩展方法。

【讨论】:

  • 是的,就是这样!我不想在项目中包含更多的外部,所以我会寻找另一种方法来做到这一点。
【解决方案2】:

我尝试和 Kjensen 做同样的事情,但我遇到了很多问题(包括原始 C# 示例存在一些错误:重新访问页面,省略了一些结果)。所以,我决定使用存储过程修改 Phil Haack (http://haacked.com/archive/2009/04/14/using-jquery-grid-with-asp.net-mvc.aspx) 的示例(我从不相信生成 SQL 代码的 ORM 事物,存储过程不是最好的,但来自 Linq 的代码也不是)和 vb。 net(我还没有清理代码,一些 cmets 是西班牙语)

SQL 代码

   Create procedure getDataPage1 
    (@tableName as varchar(100), 
    @columns as varchar(200),
    @columnOrder as varchar(100), 
    @columnOrderDirection as varchar(20),
    @currentPage as int,
    @pageSize as int, 
    @filter as varchar(2000) = '')
    AS
    BEGIN

    -- No se debe referenciar a otras columnas Identity (para esos casos se debe hacer un conversion previa antes de hacer el INSERT INTO)
    -- Version válida para Sql server 2000, usar funcion ROW_NUMBER para SQL server 2005 o posterior
    -- Ejemplos de uso: 
    -- exec getDataPage1 'DataTarjetasProcesada', 'linea = cast(linea as varchar(100)), Tarjeta, Bloqueo, Saldo', 'Tarjeta', 'desc', 6, 800
    -- exec getDataPage1 'Question', 'Id, Votes, Title', 'Title', 'desc', 2, 10



        set nocount on

        declare @query as nvarchar(1000)

        -- Paso 1: se numera el listado
        set @query = 'Select Identifier = Identity(int, 1, 1), ' + @columns  +
                ' into #temp ' +
                ' from ' + @tableName +
                case when @filter = '' then '' else ' where ' + @filter end + 
                ' Order By ' + @columnOrder + ' ' + @columnOrderDirection
        -- Paso 2: se toma la página de consulta
        +
        ' select ' + @columns  + ' from #temp '+
        ' where Identifier between '  + cast( @pageSize * (@currentPage -1) + 1 as varchar(15)) + 
        ' and '+ cast (@pageSize*( @currentPage ) as varchar (15)) 

        EXECUTE sp_executesql @query

        set nocount off
    END

Vb .net 代码

   Function DynamicGridData(ByVal sidx As String, ByVal sord As String, ByVal page As Integer, ByVal rows As Integer) As ActionResult
        Dim context As New MvcTestApplication.modelDataContext
        Dim pageIndex As Integer = Convert.ToInt32(page) - 1
        Dim pageSize As Integer = rows
        Dim totalRecords As Integer = context.Questions.Count()
        Dim totalPages As Integer = Math.Ceiling(CDec(totalRecords) / CDec(pageSize))

        ' Establecemos la función de ordenación dependiendo del valor del 
        ' parámetro "sidx", que es el campo de orden actual
        ' Establecemos si se trata de orden ascendente o descendente, en    
        ' función del parámetro "sord", que puede valer "asc" o "desc"

        Dim results As IMultipleResults = context.getDataPage1("Question", "Id, Votes, Title", sidx, sord, page, pageSize)

        Dim questions = results.GetResult(Of Question)()

        Dim jsonData = New With { _
          .total = totalPages, _
          .page = page, _
          .records = totalRecords, _
          .rows = (From question In questions _
                    Select New With _
                    { _
                        .i = question.Id, _
                        .cell = New String() {question.Id.ToString(), question.Votes.ToString(), question.Title} _
                    } _
                     ).ToArray() _
        }

        Return Json(jsonData)

    End Function

【讨论】:

    【解决方案3】:

    OrderBy 采用 lambda 表达式;在这种情况下,C# 从传递的字符串中推断出一个。 VB,显然无法做出这样的推断。

    尝试使用OrderBy(Function(str) sidx + " " + sord)

    【讨论】:

    • 除了在 VB 中最好使用 & 进行字符串连接,虽然 + 有效。
    • 对不起。 C# 开发人员在这里。 :) 只是想帮忙。
    • 感谢您的建议,Randolpho。但它没有用。
    【解决方案4】:
    Function MemberData(
            ByVal sidx As String, 
            ByVal sord As String, 
            ByVal page As Integer, 
            ByVal rows As Integer) As JsonResult
    
        Dim allRecords As IQueryable(Of Models.Member) = 
                Me.MemberRepository.FindAllMembers
    
        Dim currentPageRecords As IQueryable(Of Models.Member)
        Dim pageIndex As Integer = page - 1
        Dim pageSize As Integer = rows
        Dim totalRecords As Integer = allRecords.Count
        Dim totalPages As Integer = CInt(Math.Ceiling(totalRecords / pageSize))
    
        Dim orderBy As String = sidx + " " + sord
    
        currentPageRecords = allRecords.OrderBy(Function(m) orderBy).Skip(
                pageIndex * pageSize).Take(pageSize)
    
        Dim jsonData = New With { _
              .total = totalPages, _
              .page = page, _
              .records = totalRecords, _
              .rows = New ArrayList _
            }
    
        For Each member As Models.Member In currentPageRecords
            jsonData.rows.Add(
               New With {.id = member.MemberId, .cell = GenerateCellData(member)})
        Next
    
        Return Json(jsonData)
    
    End Function
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多