MongoDB.net 驱动程序 - 项目到不同的类

lav*_*tnc 2 .net c# mongodb aggregation-framework mongodb-.net-driver

当尝试将类型化文档投影到不同的类中时,我得到以下信息:在表达式树 new NewItem({document}, 1021) 中的类型“ NewItem ”上找不到构造函数参数“origItem”的成员匹配。

类的简化示例如下:

public class OriginalItem
{
    public ObjectId Id { get; set; }
    public string Name { get; set; }
    public IList<double> Data { get; set; }
    
    public OriginalItem() { }
}
public class NewItem
{
    public ObjectId Id { get; set; }
    public string Name { get; set; }
    public double Value { get; set; }
    
    public NewItem() { }
    public NewItem( OriginalItem origItem, int targetIdx )
    {
        Id = origItem.Id;
        Name = origItem.Name;
        Value = origItem.Data[targetIdx];
    }
}
Run Code Online (Sandbox Code Playgroud)

出现问题的示例如下:

IList<ObjectId> ids; // list of OriginalItem Ids to get
IMongoCollection<OriginalItem> collection = _db.GetCollection<OriginalItem>("items");
int targetIdx = 50;

IList<NewItem> newItems = await collection.Aggregate()
                         .Match( item => ids.Contains( item.Id ) )
                         .Project( origItem => new NewItem( origItem, targetIdx ) )
                         .ToListAsync();
Run Code Online (Sandbox Code Playgroud)

我环顾四周,似乎我唯一的选择是项目并将 origItem 转换BsonDocument ,并将其反序列化为NewItem。我还测试过更改new NewItem( origItem, targetIdx )new NewItem { //... }有效。

我知道我可以简单地读取该项目并在 mongo 服务器之外执行必要的转换,但真正的用例稍微复杂一些,我想至少弄清楚我无法理解的内容。

谢谢

Mic*_*ael 5

我也遇到过这个问题。在网上搜索了一段时间后,我终于发现使用 的Builder方法Project.Expression是唯一有效的方法。对于您的场景,它将导致类似以下内容的结果

var project = Builders<OriginalItem>.Projection.Expression(item => new NewItem(origItem, targetInx));

IList<NewItem> newItems = await collection.Aggregate()
                         .Match( item => ids.Contains( item.Id ) )
                         .Project(project)
                         .ToListAsync();
Run Code Online (Sandbox Code Playgroud)

我还删除了所有构造函数逻辑,而是让它直接进行赋值。所以 new NewItem(origItem, targetInx)你最终会得到类似的东西new NewItem(item.Id, item.Name, item.Data[targetIdx])。我不确定这一步是否必要,但如果上述方法不起作用,那么我肯定也会尝试这个。