1

I have the classes:

public class Whole
{
  public ObjectId Id { get; set; }
  public string NeededField { get; set; }
  public List<Detail> Details { get; set; }
  public string SomeUnnecesaryField { get; set; } 
}

public class Detail
{
  public string NeededField { get; set; }
  public string NotNeededField { get; set; }
}

[BsonNoId]
[BsonIgnoreExtraElements]
public class MyNeededInformations
{
  public string NeededField { get; set; }
  [BsonElement("Details.NeededField")]
  public List<string> DetailsNeededFields { get; set; }
}

And I trying to obtain it with projection:

var filter = someFilter;
var projection = Builders<Whole>.Projection
  .Include(w => w.NeededField)
  .Include(w => w.Details)
  .Exclude("_id");
return Collection
  .Find(filter)
  .Project(projection)
  .As<MyNeededInformations>()
  .ToList();

And I receive DetailsNeededFields as empty list every time. I want to have list of strings like with standard aggeregate:

db.collection.aggregate([
  {$match: someFilter},
  {$project: {"_id": 0, "NeededField": 1, "DetailsNeededFields": "$Details.NeededField"}}
])
4
  • Shouldn't the element that you're trying to call "Details.NeededField" not simply be "Details" and be a List<Detail> rather than a List<string>? Commented Mar 29, 2021 at 6:31
  • @Llama It is small reproduceable example, in real project Details have many fields, where I need only one of them Commented Mar 29, 2021 at 6:44
  • 1
    But you're asking for the equivalent of an console aggregate command that I'm pretty sure is invalid. You should at least make that part of your question valid. Commented Mar 29, 2021 at 6:45
  • @Llama Projection stage in example is working now - thank you Commented Mar 29, 2021 at 7:04

1 Answer 1

1

can be achieved easily with the AsQueryable interface like so:

var results = await collection
    .AsQueryable()
    .Where(_ => true)
    .Select(w => new MyNeededInformations
    {
        NeededField = w.NeededField,
        DetailsNeededFields = (List<string>)w.Details.Select(d => d.NeededField)
    })
    .ToListAsync();
Sign up to request clarification or add additional context in comments.

3 Comments

Will the (List<string>)w.Details.Select(d => d.NeededField) be translated to project only one field, or all details will be downloaded? Is it better than w.Details.Select(d => d.NeededField).ToList()?
@LeszekMazur yes only the needed field values will be downloaded. and you can't call ToList() as it's not translatable by the driver.
Is there a way to do this with an IAggregateFluent<T> from an aggregation? AsQueryable() can't be used in this case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.