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

3
我在使用运行Mongo 3.0的2.1 C#驱动程序时,在Mongo上有以下LINQ表达式问题。选择Id没有问题,但选择A会出现问题。
下面的简单测试演示了我遇到的错误。 “指定的方法不受支持。 MongoDB.Driver.Linq.Processors.AccumulatorBinder.GetAccumulatorArgument(Expression node)”
如果它不受支持,你有什么建议可以解决此问题,而无需首先取消查询?我知道我可以使用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; }
    }

我在遇到完全相同的问题后,在 https://dev59.com/O5Tfa4cB1Zd3GeqPLQ-U#45887800 回答了一个非常类似的问题 -- 我的 groupBy(z=>z.key).select(z=>z.first()) 返回了一个包含空项目的数组。 - scaryman
1个回答

5
我发现了另一个Stack Overflow问题的答案。问题在于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();

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? 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.

所以针对您的情况,您应该只需要执行以下操作:
allA.GroupBy(x => x.Group).Select(x => new A 
{ 
    Id = x.First().Id, 
    Group = x.First().Group 
}).ToArray();

我在查看这个问题是否仍然存在时才发现了你的问题,而不幸的是它似乎仍然存在。


有趣。当运行您的建议时,ID最终变成了null。 - SJFJ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接