【问题标题】:Using First() with OrderBy and DynamicQuery in One-To-Many related tables在一对多相关表中使用 First() 和 OrderBy 和 DynamicQuery
【发布时间】:2010-08-18 17:58:57
【问题描述】:

注意:我知道这个问题与another question 类似,但是这个问题是在 Genom-e 的上下文中提出的,但仍未得到解答。我的问题是在 LINQ DynamicQuery 的上下文中。

我正在使用System.Linq.Dynamic 提供的OrderByString 扩展方法重载。将字符串文字传递给OrderBy 效果很好。我可以对主要实体字段进行排序,即:person.OrderBy("LastName"),只要父子实体之间存在一对一的关系,我就可以对子实体字段进行排序,即:person.OrderBy("Mother.LastName")

但是,如果与父母和孩子存在一对多关系,我无法对孩子的字段进行排序,即:person.OrderBy("Children.LastName")。这会引发错误:No property or field 'Children' exists in type 'Person'

显然这会失败,因为解释器不知道 哪个 孩子的LastName 我试图在排序操作中使用。我可以通过创建像 (Function(p As Person) p.Children.First.LastName) 这样的表达式轻松解决这个问题。

但是,当使用OrderBy 的字符串文字扩展时,我怎样才能获得类似的First 行为?最终我希望能够做这样的事情:person.OrderBy("it.Lastname desc, Children.First().FirstName asc")

编辑:我正在使用存储库模式,这就是我的Find 函数的样子:

Public Function Find(ByVal predicate As Expression(Of Func(Of TEntity, Boolean)), ByVal orderBy As String, ByVal skip As Integer, ByVal take As Integer) As IEnumerable(Of TEntity) Implements ILinqSqlRepository(Of TEntity, TContext).Find

        If String.IsNullOrEmpty(orderBy) Then
            Return Find(predicate, skip, take)
        Else
            Dim qry = Context.GetTable(Of TEntity)().Where(predicate).OrderBy(orderBy).Skip(skip).Take(take)
            Return qry.ToList()
        End If

    End Function

编辑:这是PersonChild表之间的关系:

Person Table
  PersonId (pk)
  MotherId (fk to Mother Table)
  LastName
  FirstName

Child Table
  ChildId (pk)
  PersonId (fk to Person Table)
  LastName
  FirstName

Mother Table
  MotherId (pk)
  LastName
  FirstName

每个Person 可能有0 个或多个Children。您可以看到每个 Person 可以有 0 或 1 个 Mother 行。

显然这些不是我在实际项目中使用的确切表名,但您可以看到PersonMother 之间的关系以及PersonChild 之间的关系有何不同。

选择器
我尝试重载Find() 以接受Selector,它选择p = Personchild = First().Child,但返回类型更改为匿名,而不是通用类型。有什么方法可以在OrderBy 进程中使用Selector,但仍然返回IEnumerable(of TEntity)

【问题讨论】:

  • person和children表是什么关系?
  • 编辑:格式混乱。每个 Person 行有 0-n 个子行。例如:Table Person: PersonId (pk), Table Child: ChildId (pk), PersonId (fk to Person table), LastName

标签: linq linq-to-sql sql-order-by one-to-many dynamicquery


【解决方案1】:

你可以这样做(C#,抱歉...):

people.Select(p => Person = p, Child = p.Children.First())
      .OrderBy("Child.LastName")
      .Select(p => p.Person);

顺便说一句,没有"it.,您使用的是System.Linq.Dynamic,而使用"it.,您使用的是ESQL。任何一个都可以,但你不应该同时使用!

【讨论】:

  • 克雷格,感谢您的评论。我手动输入了代码 sn-ps,不小心添加了it.。我没有在实际代码中使用它。我更新了问题以显示我如何使用存储库模式,传入条件谓词。我不确定如何在 Find 函数中添加选择器并仍然保持函数通用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 2011-09-17
  • 2016-06-08
  • 1970-01-01
  • 2021-10-04
  • 1970-01-01
相关资源
最近更新 更多