简体   繁体   English

MongoDB C# 驱动程序 2.1 中 GroupBy 上的 LINQ 选择

[英]LINQ Select on GroupBy in MongoDB C# driver 2.1

I'm having problem the following LINQ expression on Mongo using the 2.1 C# driver running Mongo 3.0.我在使用运行 Mongo 3.0 的 2.1 C# 驱动程序的 Mongo 上遇到以下 LINQ 表达式问题。 Selecting the Id works fine but not selecting the A.选择 Id 工作正常但不选择 A。

The following simple test demonstrates the error I'm getting.以下简单测试演示了我遇到的错误。

Specified method is not supported.不支持指定的方法。 at MongoDB.Driver.Linq.Processors.AccumulatorBinder.GetAccumulatorArgument(Expression node)在 MongoDB.Driver.Linq.Processors.AccumulatorBinder.GetAccumulatorArgument(表达式节点)

If it is not supported, any suggestions how to work around it without having to unwind the queryable first?如果它不受支持,有什么建议可以解决它而不必先展开可查询的吗? I know that I could use the mongo aggregate framework but that is not desired since we are not exposed to that here and I do not want mongo specific syntax at this level.我知道我可以使用 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; }
    }

I stumbled across an answer from another Stack Overflow question.我偶然发现另一个 Stack Overflow 问题的答案 The issue is the First() call itself.问题是First()调用本身。

Quoting octavioccl from that answer:从那个答案中引用 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();

Now you may wondering why I had to project the result to a new instance of Status class if I could get the same result calling First extension method from each group?现在您可能想知道,如果我可以从每个组调用First扩展方法获得相同的结果,为什么我必须将结果投影到Status类的新实例? Unfortunately that is not supported yet.不幸的是,目前还不支持。 One of the reason is because the Linq provider is using [$first][1] operation when it build the aggregation pipeline, and that is how $first operation works.原因之一是因为 Linq 提供程序在构建聚合管道时使用 [$first][1] 操作,这就是$first操作的工作方式。

So for your case, you should just be able to do:所以对于你的情况,你应该能够做到:

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

I only found your question while still seeing if this particular thing was still an issue and it still seems to be which is a little unfortunate.我只是在仍然看到这个特定的事情是否仍然是一个问题的同时发现你的问题,而且它似乎仍然是一个有点不幸的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM