我在C#Asp.Net中使用RavenDB,而我在应用OrderBy时遇到问题,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();
}
我想做的是能够根据Field值对记录进行排序(例如:对名称为'Color'的字段值的记录进行排序)
修改
为了进一步解释,我想要实现的是下面的内容,但是在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.
答案 0 :(得分:3)
所以,我设法让这个工作,所以只是分享我是如何做到的。
我必须创建一个新的索引,如下所示
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对Field值执行OrderBy(在此示例中,在Color Field中的值上)
var result = session.Advanced.LuceneQuery<Record>("Record/ByField")
.OrderBy("+Colour")
.Skip(0)
.Take(10)
.ToList();
要通过降序排序,我可以将+前缀替换为 - 前缀(-Colour),并且我可以将任何字段名称传递给此Order By。
有关在特定数据库上以编程方式安装索引的信息,请参阅Programmatically create index
有关动态索引的信息,请参阅http://ravendb.net/docs/2.0/client-api/advanced/dynamic-fields
答案 1 :(得分:1)
result.OrderBy(x => x.Field.Name)
将返回一个集合,因为LINQ不会更改调用它的集合,而是返回一个具有所需结果的新集合。
所以
result = result.OrderBy(x => x.Field.Name);