How do I get data from inner array in MongoDB using LINQ's AsQueryable()?

170 Views Asked by At

I'm unable to get data from the inner array of in MongoDB. I get the error:

BsonSerializationException: No matching creator found.

Here's a sample of my data in MongoDB, query, and environment.

{
        "Id" : 1,
        "compName" : "Samsung Electronics Co.",
        "symbol" : "005930-KRX",
        "analyst" : [
                {
                        "analystId" : 4,
                        "analystInit" : "SJ",
                        "analystFName" : "Steve",
                        "analystLName" : "Jobs",
                        "analystEmail" : "[email protected]"
                }
        ],
        "associates" : [
                {
                        "analystId" : 7,
                        "analystInit" : "BG",
                        "analystFName" : "Bill",
                        "analystLName" : "Gates",
                        "analystEmail" : "[email protected]"
                },
                {
                        "analystId" : 10,
                        "analystInit" : "MJ",
                        "analystFName" : "Michael",
                        "analystLName" : "Jordan",
                        "analystEmail" : "[email protected]"
                }
        ],
        "gics" : "75301020",
        "cusip" : null
}

POCO

[BsonIgnoreExtraElements]
class CompanyClass
{
    #region [ Properties ]
    [BsonElement("issuerId")]
    public Int32 IssuerId { get; set; }
    [BsonElement("compName")]
    public string CompName { get; set; }
    [BsonElement("symbol")]
    public string Symbol { get; set; }
    [BsonElement("analyst")]
    public IEnumerable<AnalystClass> Analyst { get; set; }
    [BsonElement("associates")]
    public IEnumerable<AnalystClass> Associates { get; set; }
    [BsonElement("gics")]
    public string Gics { get; set; }
    [BsonElement("cusip")]
    public string Cusip { get; set; }
    #endregion
}
[BsonIgnoreExtraElements]
class AnalystClass
{
    #region [ Properties ]
    [BsonElement("init")]
    public string ResAnInit { get; set; }
    [BsonElement("firstName")]
    public string ResAnFirstName { get; set; }
    [BsonElement("lastName")]
    public string ResAnLastName { get; set; }
    [BsonElement("email")]
    public string ResAnEmail { get; set; }
    #endregion
}

Query:

compCollection = GetMonDB("Companies").GetCollection<CompanyClass>("coverage");
var comps = compCollection.AsQueryable()
.Select(c => new { 
    CompName = c.CompName,
    Symbol = c.Symbol,
    ResAnsFName = c.Analyst.Select(x => x.ResAnFirstName)  <-- Problem line
    CUSIP = c.Cusip
});

I want to get this:

enter image description here

My environment:

C# MongoDB.Driver = 2.12
MongoDB = 4.2
Windows = Win10

It seems that I'm missing something obvious. What am I doing wrong?

2

There are 2 best solutions below

2
Dĵ ΝιΓΞΗΛψΚ On

simply do the projection like this:

var comps = await compCollection
    .AsQueryable()
    .Select(c => new
    {
        ...
        ResAnsFName = c.Analyst.first().ResAnFirstName
        ...
    })
    .ToListAsync();
7
Juanma Feliu On

ResAns property does not exists inside CompanyClass class so you cannot use that property. Also BsonElements does not match with your MongoDB data. Select should be enough to execute the Linq, not needed FirstorDefault or ToList().

 ResAnsFName = c.Analyst.Select(x => x.ResAnFirstName)

UPDATE

BSON:

{ 
  "_id" : ObjectId("59ce6b34f48f171624840b05"), 
  "name" : "Nikola", 
  "blog" : "rubikscode.net", 
  "age" : 30, 
  "location" : "Beograd" 
}

C# Strongly typed object:

    public class User
    {
        [BsonId]
        public ObjectId Id { get; set; }
        [BsonElement("name")]
        public string Name { get; set; }
        [BsonElement("blog")]
        public string Blog { get; set; }
        [BsonElement("age")]
        public int Age { get; set; }
        [BsonElement("location")]
        public string Location { get; set; }
    }