RavenDB Linq 查询忽略 "Select" 之后的 "Where" 和 "OrderBy" 语句

RavenDB Linq query ignores "Where" and "OrderBy" statements after "Select"

我的 RavenDB 实例中有一个文档列表。这些文档有一个嵌套对象列表,其中包含一个字符串格式的数字值。我需要在此列表的特定嵌套对象中找到具有最高值的文档。我无法控制文档布局。

这是我正在使用的查询,以及测试数据的简化版本:

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Raven.Client.Documents;
using Raven.Client.Documents.Session;
using Raven.Embedded;

namespace RavenTest
{
    class Program
    {
        static void Main(string[] args)
        {
            EmbeddedServer.Instance.StartServer();
            using (var store = EmbeddedServer.Instance.GetDocumentStore("Embedded"))
            {
                GenerateTestData(store);
                QueryForEmployeeWithHighestGenericDataValue(store);
            }
        }

        private static void QueryForEmployeeWithHighestGenericDataValue(IDocumentStore store)
        {
            using (var session = store.OpenSession())
            {
                var query = session.Query<Employee>()
                    .Where(x => x.NestedGenericData != null)
                    .Where(x => x.NestedGenericData.Any(y => y.Key == "SomeKeyToFind"))
                    .Select(x =>
                        new
                        {
                            Value = x.NestedGenericData.First(y => y.Key == "SomeKeyToFind").Value,
                            Employee = x.FirstName
                        })
                    .Where(x => x.Value != null)
                    .OrderByDescending(x => x.Value, OrderingType.AlphaNumeric);

                var employeeWithHighestValue = query.FirstOrDefault();

                if (employeeWithHighestValue.Value != "42")
                {
                    var allObjectsOrderedWithoutNulls = JsonConvert.SerializeObject(
                        query.ToList(),
                        new JsonSerializerSettings { Formatting = Formatting.Indented });

                    throw new Exception($"Should be 42, but is {employeeWithHighestValue.Value}");
                }
            }
        }

        private static void GenerateTestData(IDocumentStore store)
        {
            using (var session = store.OpenSession())
            {
                // generate Id automatically
                session.Store(new Employee
                {
                    FirstName = "John10",
                    NestedGenericData = new List<GenericData>
                        {
                            new GenericData
                            {
                                Key = "SomeKeyToFind",
                                Value = "10"
                            },
                        }
                });
                session.Store(new Employee
                {
                    FirstName = "JohnNull",
                    NestedGenericData = new List<GenericData>
                        {
                            new GenericData
                            {
                                Key = "SomeKeyToFind",
                                Value = null
                            },
                        }
                });
                session.Store(new Employee
                {
                    FirstName = "John3",
                    NestedGenericData = new List<GenericData>
                        {
                            new GenericData
                            {
                                Key = "SomeKeyToFind",
                                Value = "3"
                            },
                        }
                });
                session.Store(new Employee
                {
                    FirstName = "John42",
                    NestedGenericData = new List<GenericData>
                        {
                            new GenericData
                            {
                                Key = "SomeKeyToFind",
                                Value = "42"
                            },
                        }
                });
                session.Store(new Employee
                {
                    FirstName = "JohnNoGenericData",
                    NestedGenericData = new List<GenericData>
                        {
                            new GenericData
                            {
                                Key = "SomeOtherKey",
                                Value = "123"
                            },
                        }
                });
                session.Store(new Employee
                {
                    FirstName = "John1",
                    NestedGenericData = new List<GenericData>
                        {
                            new GenericData
                            {
                                Key = "SomeKeyToFind",
                                Value = "1"
                            },
                            new GenericData
                            {
                                Key = "SomeOtherKey",
                                Value = "123"
                            },
                        }
                });

                // send all pending operations to server, in this case only `Put` operation
                session.SaveChanges();
            }
        }
    }

    internal class GenericData
    {
        public string Key { get; set; }
        public string Value { get; set; }
    }

    internal class Employee
    {
        public string FirstName { get; set; }
        public List<GenericData> NestedGenericData { get; set; }
    }
}

如果将此代码粘贴到安装并执行 Install-Package RavenDB.Embedded -Version 4.1.0 的新 .NET 核心控制台应用程序中,将 return employeeWithHighestValueValue 字段等于 "10" 并且 Employee 字段等于 "John10".

allObjectsOrderedWithoutNulls 的值(即整个查询的转储)将包含:

[
  {
    "Value": "10",
    "Employee": "John10"
  },
  {
    "Value": null,
    "Employee": "JohnNull"
  },
  {
    "Value": "3",
    "Employee": "John3"
  },
  {
    "Value": "42",
    "Employee": "John42"
  },
  {
    "Value": "1",
    "Employee": "John1"
  }
]

这既没有过滤掉带有 x.Value == null 的投影条目,也没有按 Value 字段(AlphaNumerically 或其他)降序排列。

问题:

我的查询有什么问题?

为什么 Select 之后的 LINQ 语句似乎不适用?

获取我需要的数据的正确方法是什么?

您在查询中使用了“.Select”,这是一个“Projection”。

投影只能作为查询管道中的 last 阶段应用 - 在文档被处理、过滤、排序和分页之后。 所以你不能在 Select.

之后应用 Where

参见:Projecting Individual Fields

参见:Query Example