[CSHARP-1306] Projecting an enumerable as a top-level enumerable doesn't deserialize properly Created: 10/Jun/15  Updated: 12/Jun/15  Resolved: 12/Jun/15

Status: Closed
Project: C# Driver
Component/s: Linq
Affects Version/s: 2.1
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Craig Wilson Assignee: Craig Wilson
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

public static async Task TestAsync()
{
    var client = new MongoClient();
    var db = client.GetDatabase("test");
    var col = db.GetCollection<User>("users");
 
    await db.DropCollectionAsync("users");
 
    await col.InsertOneAsync(new User
    {
        Id = "1",
        AppIntegrations = new[] 
        { 
            new UserAppIntegration { AppName = "App1", CanRemove = true },
            new UserAppIntegration { AppName = "App2", CanRemove = false },
        }
    });
 
    var pipeline = col.Aggregate()
        .Match(u => u.Id == "1")
        .Project(u => u.AppIntegrations.Select(i => new UserAppIntegrationStatus { AppName = i.AppName, CanRemove = !i.CanRemove }));
 
    var results = await pipeline.ToListAsync();
 
    //warm up
 
    Console.ReadKey();
}
 
public class User
{
    public User()
    {
        AppIntegrations = new UserAppIntegration[0];
    }
 
    public string Id { get; set; }
    public string Email { get; set; }
    public UserAppIntegration[] AppIntegrations { get; set; }
}
 
public class UserAppIntegration
{
    public string AppName { get; set; }
    public bool CanRemove { get; set; }
}
 
public class UserAppIntegrationStatus
{
    public string AppName { get; set; }
    public bool CanRemove { get; set; }
}

Workaround

Instead of projecting the enumerable directly, wrap it in a type:

var pipeline = col.Aggregate()
                .Match(u => u.Id == "1")
                .Project(u => new { SomeField = u.AppIntegrations.Select(i => new UserAppIntegrationStatus { AppName = i.AppName, CanRemove = !i.CanRemove }) });



 Comments   
Comment by Craig Wilson [ 12/Jun/15 ]

This is also documented here: http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/crud/reading/#project.

Comment by Craig Wilson [ 12/Jun/15 ]

This works by design. MongoDB expects documents at the output of each pipeline and, because this is not IQueryable, we don't have access to the entire pipeline. Therefore, we cannot bypass this restriction. Hence, the "workaround" described in the ticket will be the solution.

Generated at Wed Feb 07 21:39:14 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.