【问题标题】:Use LINQ Query with in-line function - sorted by function使用带有内联函数的 LINQ 查询 - 按函数排序
【发布时间】:2014-05-21 17:52:30
【问题描述】:

我正在尝试设置一个 LINQ 查询以用作组合框数据源。组合框是 DisplayMember 的名称和 ValueMember 的 PeopleID 的简单列表。

问题是名称可以是 First Last 或 Last, First 格式。我有一个 GetFullName(intPeopleID) 函数来返回正确的名称序列。无论哪种方式,组合框名称都必须按字母顺序排序,因此需要在第一个查询获得全名后进行排序。

Dim LQBackupOriginalA = From a In DCAppMain.tblPeopleMain
        Where a.BusinessGroupID = intBusinessGroupID
        Select Person = PP.GetFullName(a.PeopleID), a.PeopleID

Dim LQBackupOriginalB = From b In LQBackupOriginalA
    Order By b.Person
    Select b.Person, b.PeopleID

cboBackupOriginal.DataSource = LQBackupOriginalA
cboBackupOriginal.DisplayMember = "Person"
cboBackupOriginal.ValueMember = "PeopleID"

这不起作用,因为函数 'GetFullName' 不能转换为 SQL - 当然。我已经尝试了很多变体,但都没有成功。

我可以首先将第一个查询中的数据附加到本地表中,然后在设置组合框的数据源之前使用对数据进行排序的查询将其拉回。但我想知道是否有更直接的方法?

【问题讨论】:

  • 看起来PP.GetFullName 做了额外的数据库查询。在主查询中获取所需数据并提供 PP.GetFullName 完成其工作所需的所有数据可能要高效得多。
  • 格特 - 你是对的。这将获取名字和姓氏,然后根据客户的偏好将这两个单词按顺序排列,这可能是任何一种方式。然后 QueryB 需要按 FullName(First Last 或 Last, First)排序,无论客户希望以哪种方式显示名称。我想知道该怎么做?

标签: vb.net winforms linq combobox datasource


【解决方案1】:

您应该能够只过滤您想要的行,将查询转换为可枚举并在内存中执行 GetFullName 部分。我的VB缺少,但类似的东西;

Dim LQBackupOriginalA = (
    From a In DCAppMain.tblPeopleMain
    Where a.BusinessGroupID = intBusinessGroupID
    Select a.PeopleID).
         AsEnumerable().
         Select(Function(peopleId) New With {
            Key .Person = PP.GetFullName(peopleId), .PeopleID = peopleId
         })

...或在我确定语法的 C# 中;

var LQBackupOriginalA = 
    DCAppMain.tblPeopleMain
        .Where(a => a.BusinessGroupID == intBusinessGroupID)
        .Select(a => a.PeopleID)
        .AsEnumerable()
        .Select(peopleId => 
                  new {Person = PP.GetFullName(peopleId), PeopleID = peopleId});

【讨论】:

  • 您好 Joachim - 感谢您的回复。但是,我确实需要此查询中的所有行,它只需要按 FullName 排序,无论 FullName 是 FirstLast 还是 LastFirst。这就是第二个查询试图做的事情,这就是发生错误的地方。
  • @DanW52 这不是给出相同的行吗?
  • 嗨 Joachim - 你能把它放到 C# 中吗 - 我可以用代码转换器翻译。
  • @DanW52 用 C# 更新。
【解决方案2】:

感谢 Joachim - 到目前为止我还没有尝试过使用 lambda 函数,它们很有帮助!

这就是我最终所做的,确实有效:

    '-- Get Distinct ManagerID
    Dim LQManagerOriginalA = (From a In DCAppMain.tblPeopleMain
        Where a.ManagerID IsNot Nothing And a.CurrentEmployee = True And a.UserType = "Full"
        Group By a.ManagerID Into g = Group
        Order By ManagerID
        Select New With {.ManagerID = ManagerID})

    '-- Get Ordered List of FullNames and PeopleIDs
    Dim LQManagerOriginalB = LQManagerOriginalA.[Select](Function(a) a.ManagerID).AsEnumerable().[Select](Function(a) New With {Key .Person = PP.GetFullName(a), Key .PeopleID = a}).OrderBy(Function(x) x.Person).ToList()

    '-- Apply datasource to combobox        
    RemoveHandler cboManagerOriginal.SelectedIndexChanged, AddressOf cboManagerOriginal_SelectedIndexChanged
    cboManagerOriginal.DataSource = LQManagerOriginalB
    AddHandler cboManagerOriginal.SelectedIndexChanged, AddressOf cboManagerOriginal_SelectedIndexChanged
    cboManagerOriginal.DisplayMember = "Person"
    cboManagerOriginal.ValueMember = "PeopleID"

【讨论】:

    猜你喜欢
    • 2012-07-24
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-11
    相关资源
    最近更新 更多