2015-11-25 3 views
1

У меня возникла проблема с выражением LINQ на Mongo с использованием драйвера 2.1 C#, работающего с Mongo 3.0. Выбор Id работает нормально, но не выбирает A.LINQ Выберите в GroupBy в MongoDB C# драйвер 2.1

Следующий простой тест демонстрирует ошибку, которую я получаю.

Указанный способ не поддерживается. в 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; } 
    } 
+0

Я ответил на очень похожий вопрос на https://stackoverflow.com/a/45887800/346272 после того, как столкнулся с одной и той же проблемой - моя группаBy (z => z.key) .select (z => z.first()) возвращает массив нулевых элементов. – scaryman

ответ

0

я наткнулся на 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(); 

Теперь вы можете задаваться вопросом, почему я должен был проецировать результат в новый экземпляр Status класса, если я мог бы получить тот же результат, вызывая First метод расширения от каждого группа? К сожалению, это еще не подтверждено. Одна из причин заключается в том, что поставщик Linq использует операцию [$ first] [1], когда он создает конвейер агрегации, и именно так работает $first.

Так что для вашего дела, вы просто должны быть в состоянии сделать:

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

Я только нашел ваш вопрос пока еще видеть, если эта конкретная вещь была еще проблема, и она по-прежнему кажется, что немного неудачно.

+0

Интересно. При выполнении вашего предложения Id заканчивается тем же, что и null. – SJFJ

Смежные вопросы