LINQ - VB.Net中的动态OrderBy

时间:2009-05-27 19:25:36

标签: c# .net vb.net linq

我正在尝试做一些类似于Phil Haack到VB的示例代码,LINQ Orderby给我带来了问题 - 我无法弄清楚如何做到这一点。发布整个方法for completenes。

这是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”...

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

EDIT2:

根据要求提供更多信息。 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

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

我尝试和Kjensen一样,但是我遇到了很多问题(包括原始的C#样本有一些错误:重新查看一些结果被忽略的页面)。因此,我决定使用存储过程修改Phil Haack(http://haacked.com/archive/2009/04/14/using-jquery-grid-with-asp.net-mvc.aspx)的示例(我从不信任生成SQL代码的ORM事物,存储过程不是最好的,但Linq的代码都没有)和VB。 net(我没有清理代码,有些评论是西班牙语)

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 Code

   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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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
相关问题