如何在 RavenDB 中按上次修改顺序排序?

How to order by last modified in RavenDB?

我正在尝试使用 OData 查询选项让我的实体按其元数据中的 Last-Modified 属性 进行排序。

我尝试使用 Converting to JSON and accessing metadata 中描述的转换器,但是当我将 ODataQueryOptions 应用于结果 IQueryable 时,我得到一个空数组。

模型和视图模型:

public class Foo
{
    public int Id { get; set; }
}

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

    public DateTime LastModified { get; set; }
}

变压器:

public class Foos_WithLastModified : AbstractTransformerCreationTask<Foo>
{
    public Foos_WithLastModified()
    {
        TransformResults = foos => from foo in foos
            let metadata = MetadataFor(foo)
            select new
            {
                Id = foo.Id.ToString(CultureInfo.InvariantCulture),
                LastModified = metadata.Value<DateTime>("Last-Modified")
            };
    }
}

FooController中的相关方法(_session是一个IAsyncDocumentSession):

public async Task<ICollection<FooViewModel>> Get(ODataQueryOptions<FooViewModel> options)
{
    var settings = new ODataValidationSettings();
    settings.AllowedOrderByProperties.Add("LastModified");

    options.Validate(settings);

    var foos = _session.Query<Foo>()
        .TransformWith<Foos_WithLastModified, FooViewModel>();
    var odataFoos = (IQueryable<FooViewModel>)options.ApplyTo(foos);
    return await odataFoos.ToListAsync();
}

当我点击/api/Foo时,结果如预期:

[
  {
    "Id": "foos/456",
    "LastModified": "2015-11-23T08:43:10.913662Z"
  },
  {
    "Id": "foos/123",
    "LastModified": "2015-11-23T08:50:34.0907996Z"
  }
]

但是当我添加 OData 查询选项 (/api/Foo?$orderby=LastModified) 时,我得到一个空数组:[].

我还尝试将 _session 更改为 IDocumentSession 并按如下方式修改 Get

[EnableQuery(AllowedOrderByProperties = "LastModified")]
public IQueryable<FooViewModel> Get()
{
    return _session.Query<Foo>()
        .TransformWith<Foos_WithLastModified, FooViewModel>();
}

但我得到了相同的结果。

变形金刚是错误的方法吗?如何使用 OData 查询选项按 Last-Modified 排序?

我不知道如何处理 OData 的东西,从未尝试过,但是为了查询实体,仅使用 RavenDB 技术 "Last-Modified" 按元数据值排序,您可以执行以下操作:

为您的实体创建一个索引(在我的例子中是 Customer)。在此索引中,我们添加字段 LastModified,该字段使用 Last-Modified.

的文档元数据值
public class Customer_ByLastModified : AbstractIndexCreationTask<Customer>
{
    public class QueryModel
    {
        public DateTime LastModified { get; set; }
    }

    public Customer_ByLastModified()
    {
        Map = customers => from customer in customers
            select new
            {
                LastModified = this.MetadataFor(customer).Value<DateTime>("Last-Modified")
            };
    }
}

QueryModel 不是强制性的,但它使通过客户端 API 进行查询更容易,imo。然后,您可以添加一个转换器,以便能够在您的 return 模型中使用元数据值:

public class Customers_WithLastModified : AbstractTransformerCreationTask<Customer>
{
    public Customers_WithLastModified()
    {
        TransformResults = results => from customer in results
            select new CustomerViewModel
            {
                Id = customer.Id,
                Name = customer.Name,
                LastModified = MetadataFor(customer).Value<DateTime>("Last-Modified")
            };
    }
}

然后这样查询:

using (var session = documentStore.OpenSession())
{
    var customers = session.Query<Customer_ByLastModified.QueryModel, Customer_ByLastModified>()
        .OrderByDescending(x => x.LastModified)
        .TransformWith<Customers_WithLastModified, CustomerViewModel>()
        .ToList();
}

希望对您有所帮助!