如何使用 LINQ 的 AsQueryable() 从 MongoDB 的内部数组中获取数据?

Posted

技术标签:

【中文标题】如何使用 LINQ 的 AsQueryable() 从 MongoDB 的内部数组中获取数据?【英文标题】:How do I get data from inner array in MongoDB using LINQ's AsQueryable()? 【发布时间】:2021-03-25 14:54:55 【问题描述】:

我无法从 MongoDB 的内部数组中获取数据。我得到了错误:

BsonSerializationException: No matching creator found.

这是我在 MongoDB、查询和环境中的数据示例。


        "Id" : 1,
        "compName" : "Samsung Electronics Co.",
        "symbol" : "005930-KRX",
        "analyst" : [
                
                        "analystId" : 4,
                        "analystInit" : "SJ",
                        "analystFName" : "Steve",
                        "analystLName" : "Jobs",
                        "analystEmail" : "steve.jobs@apple.com"
                
        ],
        "associates" : [
                
                        "analystId" : 7,
                        "analystInit" : "BG",
                        "analystFName" : "Bill",
                        "analystLName" : "Gates",
                        "analystEmail" : "bill.gates@microsoft.com"
                ,
                
                        "analystId" : 10,
                        "analystInit" : "MJ",
                        "analystFName" : "Michael",
                        "analystLName" : "Jordan",
                        "analystEmail" : "michael.jordan@nba.com"
                
        ],
        "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

查询:

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
);

我想得到这个:

我的环境:

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

我似乎遗漏了一些明显的东西。我做错了什么?

【问题讨论】:

【参考方案1】:

只需像这样进行投影:

var comps = await compCollection
    .AsQueryable()
    .Select(c => new
    
        ...
        ResAnsFName = c.Analyst.first().ResAnFirstName
        ...
    )
    .ToListAsync();

【讨论】:

对不起@Đĵ ΝιΓΞΗΛψΚ。那没有用。当我做那个投影时,我仍然遇到同样的错误。 :( @inquisitive_one 如果您将this 扔到控制台应用程序中,那么您会看到它运行良好。【参考方案2】:

ResAns 属性在 CompanyClass 类中不存在,因此您不能使用该属性。 BsonElements 也与您的 MongoDB 数据不匹配。 Select 应该足以执行 Linq,不需要 FirstorDefault 或 ToList()。

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

更新

BSON:

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

C# 强类型对象:

    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; 
    

【讨论】:

对不起。你说得对。我更新了我的帖子以在 CompanyClass 类中显示 Analyst 而不是 ResAns。我已经尝试了您的建议,但仍然遇到同样的错误: 在哪个班? CompanyClass 还是 AnalystClass?你有什么建议? 两个类:[BsonElement("issuerId")] = [BsonElement("Id")] [BsonElement("firstName")] = [BsonElement("analystFName")] ...跨度> 我怕我糊涂了。我不明白更改 BsonElement 名称会有什么帮助。 将 BSON 映射到强类型 C# 对象。

以上是关于如何使用 LINQ 的 AsQueryable() 从 MongoDB 的内部数组中获取数据?的主要内容,如果未能解决你的问题,请参考以下文章

linq中AsEnumerable和AsQueryable的区别

LINQ语句中的.AsEnumerable() 和 .AsQueryable()的区别

选择 ID 字段的 AsQueryable linq 语句

Enumerable.Empty<T>().AsQueryable();此方法支持 LINQ to Entities 基础结构,不打算直接从您的代码中使用

如何使用 Linq 在 Mongo C# 2.2 驱动程序中查询嵌套列表?

如何将字典结果绑定到类对象c#linq