在保留类型信息的同时使用 Slice 投影

Using the Slice projection while preserving type information

我有一个名为 Student 的类型,它具有三个属性:

| Student                |
|------------------------|
| Id: string             |
| Name: string           |
| CoursesTaken: string[] |

CoursesTaken 属性 保存所修课程的 ID,按照课程的顺序排列,因此该数组中的最后一个元素将是学生所修最后一门课程的 ID .

现在我想查询 上一门课程 是 X 的学生的集合。我猜 ProjectionDefinitionBuilder<Student>.Slice 是要使用的方法。

而且我不想求助于 BsonDocuments,因为我想在整个过程中保留类型推断,因为我稍后会添加更多过滤器。所以我想传递一个 IAggregateFluent<Student> 并且我想要一个 IAggregateFluent<Student> 返回。

有没有办法实现这个?

更新:

我无法让 Ryan 的示例(如下)起作用的原因是我实际上并没有完全遵循它。这是我发现的:

// This doesn't work (throws a NotSupportedException):
contacts.Aggregate()
    .Project(s => new
    {
        Fruit = s,
        LastNode = s.Path.Last()
    })
    .Match(x => x.LastNode == "avacados")
    .Project(x => x.Fruit);

// But this one works:
contacts.Aggregate()
    .Project(s => new
    {
        Id = s.Id,
        Name = s.Name,
        Path = s.Path,
        LastNode = s.Path.Last()
    })
    .Match(x => x.LastNode == "avacados")
    .Project(x => new Fruit
    {
        Path = x.Path,
        Id = x.Id,
        Name = x.Name
    });

这似乎可行,但由于投影的缘故,它并不理想。

            var query = collection.Aggregate()
                                  .Project(s => new
                                  {
                                      s.Id,
                                      s.Name,
                                      s.CoursesTaken,
                                      lastCourse = s.CoursesTaken.Last()
                                  })
                                  .Match(x => x.lastCourse == "avacados")
                                  .Project(x => new Student
                                  {
                                      Id = x.Id,
                                      Name = x.Name,
                                      CoursesTaken = x.CoursesTaken
                                  });

这是一个完整的测试程序

using MongoDB.Driver;
using MongoDB.Entities;
using MongoDB.Entities.Core;
using System.Linq;

namespace Whosebug
{
    public class Student : Entity
    {
        public string Name { get; set; }
        public string[] CoursesTaken { get; set; }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            new DB("test", "localhost");

            (new Student
            {
                Name = "Harry Potter",
                CoursesTaken = new[] { "spells", "broomsticks", "avacados" }
            }).Save();

            var query = DB.Fluent<Student>()
                          .Project(s => new
                          {
                              s.ID,
                              s.Name,
                              s.CoursesTaken,
                              lastCourse = s.CoursesTaken.Last()
                          })
                          .Match(x => x.lastCourse == "avacados")
                          .Project(x => new Student
                          {
                              ID = x.ID,
                              Name = x.Name,
                              CoursesTaken = x.CoursesTaken
                          })
                          .ToList();            
        }
    }
}