【问题标题】:OrderBy on a Sub Collection using RavenDB使用 RavenDB 对子集合进行 OrderBy
【发布时间】:2013-07-17 16:32:46
【问题描述】:

我在 C# Asp.Net 中使用 RavenDB,但在应用按子集合中的值排序的 OrderBy 时遇到问题。我的模型的一个基本示例是:

public class Record
{
    public string Id { get; set; }

    public string Name {get; set; }

    public Field[] Fields { get; set; }
}

public class Field
{
    public string Name { get; set; }

    public string Value { get; set; }
}

这样可以保存到 RavenDB 中

{
   "Name": "A Name Of Somesort"
   "Fields": [
       {
          "Name": "Colour",
          "Value": "Red"
       },
       {
          "Name": "Size",
          "Value": "Large"
       }
   ]
}

想象一下大量的这些记录保存到数据库中,我可以像这样得到这些数据的页面

using (var session = documentStore.OpenSession("TestDB"))
{
    var result = session.Query<Record>().Skip(0).Take(10).ToList();
}

我想做的是能够根据字段值对记录进行排序(例如:根据名称为“颜色”的字段的值对记录进行排序)

编辑:

为了帮助进一步解释,我想要实现的是如下所示,但是在 RavenDB 中这是不允许的,所以我需要找到一种替代方法(如果可能的话)

using (var session = documentStore.OpenSession("TestDB"))
{
    var result = session.Query<Record>()
                .OrderBy(v => v.Fields.First(f => f.Name == "Colour").Value)
                .Skip(0)
                .Take(10)
                .ToList();
}

这会引发一个带有以下消息的新 ArgumentException

Invalid computation: v.Fields.First(f => (f.Name == "Colour")).Value. You cannot use computation (only simple member expression are allowed) in RavenDB queries.

【问题讨论】:

    标签: c# asp.net ravendb


    【解决方案1】:

    所以,我设法让这个工作,所以只是分享我是怎么做到的。

    我必须创建一个如下所示的新索引

    public class Record_ByField : AbstractIndexCreationTask<Record>
    {
        public Record_ByField()
        {
            Map = records=> from r in records
                              select new
                              {
                                  _ = r.Fields
                                     .Select(field =>
                                         CreateField(field.Name, field.Value, false, true))
                              };
        }
    }
    

    这意味着我可以使用 LuceneQuery 对字段值执行 OrderBy(在本例中,在颜色字段中的值上)

    var result = session.Advanced.LuceneQuery<Record>("Record/ByField")
                .OrderBy("+Colour")
                .Skip(0)
                .Take(10)
                .ToList();
    

    要按降序排序,我可以将 + 前缀替换为 - 前缀(-Colour),并且我可以将任何字段名称传递到此排序依据。

    有关在特定数据库上以编程方式安装索引的信息 - 请参阅 Programmatically create index

    有关动态索引的信息 - 请参阅 http://ravendb.net/docs/2.0/client-api/advanced/dynamic-fields

    【讨论】:

      【解决方案2】:

      result.OrderBy(x =&gt; x.Field.Name) 将返回一个集合,因为 LINQ 不会更改调用它的集合,而是返回一个具有所需结果的新集合。

      也是这样

      result = result.OrderBy(x => x.Field.Name);
      

      【讨论】:

      • 不确定这是我要找的。我添加了一个编辑,希望能进一步解释。我想根据其中一个字段的值对 Skip 和 Take 之前的记录列表进行排序 - 在上面的示例中,它将是具有名称颜色的字段的值(因此带有字段的记录称为蓝色的颜色和值将在一个记录上方,该记录的字段名为颜色,值为红色)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-21
      • 2013-01-27
      • 2016-10-17
      • 2011-04-06
      相关资源
      最近更新 更多