将参数从视图传递到实体框架OrderBy查询

时间:2017-03-17 19:36:52

标签: vb.net entity-framework

我想知道如何从视图中执行升序和降序查询。我目前的观点如下:

enter image description here

我知道我可以使用以下内容订购视图:

Dim retrieveOrders = context.PBBuilds.Where(Function(x) x.User = userLoggedIn.Id).OrderBy(Function(x) x.Id).ToList()

我希望通过动作链接传递列标题并升序或降序到方法? (每个标题附近的向上和向下箭头)。

OrderBy()不接受字符串....任何人都可以帮忙吗?谢谢

控制器:

   ' GET: Dashboard
    <Authorize(Roles:="Admin, Employee, User")>
    Function Index() As ActionResult

        Dim context = New ApplicationDbContext()
        Dim UserManager = New UserManager(Of ApplicationUser)(New UserStore(Of ApplicationUser)(context))
        Dim userLoggedIn = UserManager.FindById(User.Identity.GetUserId())
        Dim retrieveOrders = context.PBBuilds.Where(Function(x) x.User = userLoggedIn.Id).OrderBy(Function(x) x.Id).ToList()

        Dim BuildsVM = retrieveOrders.[Select](Function(build) New DashboardBuilds() With {
        .BuildNumber = build.Id,
        .DateCreated = build.TimeAndDate,
        .MyRef = build.CustRef,
        .NetCost = build.TotalNet
        }).ToList()

        Dim today = DateTime.Today.Date
        Dim tomorrow = DateTime.Today.Date.AddDays(1)
        Dim todaysBuild = retrieveOrders.Where(Function(build) build.TimeAndDate >= today And build.TimeAndDate <= tomorrow).ToList().Count()
        Dim monthlyBuild = retrieveOrders.Where(Function(build) build.TimeAndDate.Year = today.Year And build.TimeAndDate.Month = today.Month).ToList().Count()
        Dim yearlyBuild = retrieveOrders.Where(Function(build) build.TimeAndDate.Year = today.Year).ToList().Count()

        Dim total As Decimal = BuildsVM.Sum(Function(item) item.NetCost)
        Dim count As Integer = retrieveOrders.Count
        Dim Average As Decimal = 0.00

        If count > 0 Then
            Average = total / count
        End If


        Dim model = New GroupedDashBoardBuilds() With {
        .BuildInfos = BuildsVM,
        .TotalNet = Math.Round(total, 2),
        .AverageNet = Math.Round(Average, 2),
        .TotalUserBuild = count,
        .TotalUserBuildToday = todaysBuild,
        .TotalUserBuildMonth = monthlyBuild,
        .TotalUserBuildYear = yearlyBuild
        }

        Return View(model)
    End Function

2 个答案:

答案 0 :(得分:1)

由于您将传递字段名称以及是否要按升序或降序进入控制器:

Function Index(strColumnName As String, bolAscending As Boolean) As ActionResult

您可以在Select Case中实现逻辑,如下所示:

Dim retrieveOrders As List(Of PBBuilds) = Nothing

Select Case strColumnName
    Case "Build"
        If bolAscending Then
            retrieveOrders = context.PBBuilds.Where(Function(x) x.User = userLoggedIn.Id).OrderBy(Function(x) x.Id).ToList()
        Else
            retrieveOrders = context.PBBuilds.Where(Function(x) x.User = userLoggedIn.Id).OrderByDescending(Function(x) x.Id).ToList()
        End If
    Case "My Reference"
        If bolAscending Then
            retrieveOrders = context.PBBuilds.Where(Function(x) x.User = userLoggedIn.Id).OrderBy(Function(x) x.FieldRelatedToMyReference).ToList()
        Else
            retrieveOrders = context.PBBuilds.Where(Function(x) x.User = userLoggedIn.Id).OrderByDescending(Function(x) x.FieldRelatedToMyReference).ToList()
        End If

    'Implement for Other Cases
End Select

答案 1 :(得分:0)

如果您不关心数据库上运行的OrderBy,您可以执行以下操作:

Dictionary<string, Func<User, object>> ColumnAccessorMap = new Dictionary<string, Func<User, object>>()
{
    { "Build", user => user.ID },
    { "My Reference", user => user.MyReferenceProperty }
}

// etc...

context.MyTable.ToList().OrderBy(ColumnAccessorMap[strColumnName]);

或在VB.NET中(手工转换,很久没有使用过VB)

Dim ColumnAccessorMap as new Dictionary(of String, Object) From {{ "Build", Function(u) u.ID }, { "My Reference", Function(u) u.MyRefProperty }}

'... etc

context.MyTable.ToList().OrderBy(ColumnAccessorMap(strColumnName))

基本上,将列映射到访问器函数,该函数告诉OrderBy排序时要使用的属性。同样,如果没有.ToList之前的调用,这将无法工作,这意味着排序发生在本地,而不是在SQL中。