【问题标题】:LINQ Select on GroupBy in MongoDB C# driver 2.1MongoDB C# 驱动程序 2.1 中 GroupBy 上的 LINQ 选择
【发布时间】:2015-11-25 14:29:34
【问题描述】:

我在使用运行 Mongo 3.0 的 2.1 C# 驱动程序的 Mongo 上遇到以下 LINQ 表达式问题。选择 Id 工作正常,但不选择 A。

以下简单测试演示了我遇到的错误。

不支持指定的方法。 在 MongoDB.Driver.Linq.Processors.AccumulatorBinder.GetAccumulatorArgument(表达式节点)

如果它不受支持,有什么建议可以解决它而不必先解开可查询的?我知道我可以使用 mongo 聚合框架,但这是不希望的,因为我们在这里没有接触到它,而且我不希望在这个级别上使用 mongo 特定语法。

[Test]
    public void TestLinqSelectOnGroupBy()
    {
        MongoClient mongoClient = new MongoClient();
        var repo = mongoClient.GetDatabase("GroupSelect");

        var a = new A() { Id = "1", Group = "A" };
        var col = repo.GetCollection<A>("A");
        col.InsertOneAsync(a);
        var allA = col.AsQueryable(); // adding .ToArray(); will obviously make it work but that is not very efficient

        var works =  allA.GroupBy(x => x.Group).Select(x => x.First().Id).ToArray();
        var fails =  allA.GroupBy(x => x.Group).Select(x => x.First()).ToArray();
    }

    private class A 
    {
        public string Id { get; set; }
        public string Group { get; set; }
    }

【问题讨论】:

  • 在遇到完全相同的问题后,我在stackoverflow.com/a/45887800/346272 回答了一个非常相似的问题——我的 groupBy(z=>z.key).select(z=>z.first()) 正在返回一个空项目数组。

标签: mongodb linq mongodb-.net-driver


【解决方案1】:

我从另一个 Stack Overflow 问题中偶然发现了 an answer。问题在于 First() 调用本身。

从那个答案中引用 octavioccl:

 var statusesCollection = database.GetCollection<Status>("statuses");
 var result= statusesCollection.AsQueryable()
                               .OrderByDescending(e=>e.date)
                               .GroupBy(e=>e.payment)
                               .Select(g=>new Status{_id =g.First()._id,
                                                     payment = g.Key,
                                                     code=g.First().code,
                                                     date=g.First().date
                                                    }
                                       )
                               .ToList();

现在您可能想知道,如果我可以从每个组调用 First 扩展方法获得相同的结果,为什么我必须将结果投影到 Status 类的新实例?不幸的是,目前还不支持。原因之一是 Linq 提供程序在构建聚合管道时使用了 [$first][1] 操作,这就是 $first 操作的工作原理。

所以对于你的情况,你应该能够做到:

allA.GroupBy(x => x.Group).Select(x => new A 
{ 
    Id = x.First().Id, 
    Group = x.First().Group 
}).ToArray();

我只是在查看这个特定问题是否仍然是一个问题时才发现你的问题,而且它似乎仍然是一个有点不幸的问题。

【讨论】:

  • 有趣。在运行您的建议时,ID 最终为空。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-13
相关资源
最近更新 更多