Home > Enterprise >  'MongoDB.Driver.IFindFluent<XDocument, System.Collections.Generic.List<string>>
'MongoDB.Driver.IFindFluent<XDocument, System.Collections.Generic.List<string>>

Time:07-02

I am working on a asp.net core project with MongoDB.

I want to get a list from Database.

I tried this

public async Task<List<string>> GetRoomCodesFromHotelBooking(string transactionId)
{
  return HotelBookingCollection
    .Find(x => x.TransactionId == transactionId)
    .Project(x => x.Hotel.Rooms.Select(y => y.Code).ToList());
}

Note : A transactionId has more than one HotelBooking

But I got this error

Cannot implicitly convert type 'MongoDB.Driver.IFindFluent<xDocument, System.Collections.Generic.List<string>>' to 'System.Collections.Generic.List<string>'. An explicit conversion exists (are you missing a cast?)

model class

public class HotelBookingDocument
{
    public string Id { get; set; }
    public HotelDocument Hotel { get; set; }
// removed rest 
}

public class HotelDocument
{
    public List<RoomDocument> Rooms { get; set; }
// removed rest 
}

public class RoomDocument
{
      public string Code { get; set; }
// removed rest 
}
// removed rest 

How can I select room code and make list them?

CodePudding user response:

Up to now, the code does not result in a List<string>, but only in a fluent interface that needs to be executed. The following code returns a list of all codes:

public async Task<List<string>> GetRoomCodesFromHotelBooking(string transactionId)
{
    // get all codes as a list of arrays
    var codes = await HotelBookingCollection
      .Find(x => x.TransactionId == transactionId)
      .Project(x => x.Hotel.Rooms.Select(y => y.Code).ToList())
      .ToListAsync();
    // generate a single list of codes
    return codes
      .SelectMany(x => x)
      .Distinct()   // remove duplicates
      .ToList();
}

How does it work?

  • In the first step, the data are retrieved from MongoDB. Please note that - at least in theory - there might be many documents that fulfill the condition regarding the transactionId. So this returns a List<List<string>> - a list of list of strings.
  • In the next step, this List<List<string>> is converted into a flat List<string> by using SelectMany. Afterwards, a Distinct removes any duplicates.

Though above sample stays close to your code, you could also use an aggregation in MongoDB to achieve the same and by that, put more of the query execution onto the MongoDB cluster. The following pipeline can serve as a starting point:

[
  {$match: { TransactionId: 'T123' }}, 
  {$unwind: { path: '$Hotel', preserveNullAndEmptyArrays: false }}, 
  {$unwind: { path: '$Hotel.Rooms', preserveNullAndEmptyArrays: false }}, 
  {$project: { _id: 0, Code: '$Hotel.Rooms.Code' }}
]
  • Related