我有这个简化的模型:
public class Parent
{
public ObjectId Id { get; set; }
}
public class Child
{
public ObjectId Id { get; set; }
public ObjectId ParentId { get; set; }
[BsonRepresentation(BsonType.String)]
public Gender Gender { get; set; }
}
我已经用过滤器询问了一些我故意省略的字段的父母。现在我有一个父 ID 集合。我想获取Gender.Male
仅适用于我通过第一个查询获得的那些父母的所有孩子并将它们分组,以便我可以在 aParent
和之间进行映射List<Child>
。
var parentIds = filteredParents.Select(p => p.Id).ToList();
var childrenFilter = Builders<Child>.Filter.In(c => c.ParentId, parentIds) &
Builders<Child>.Filter.Eq(c => c.Gender, Gender.Male);
var aggregation = children
.Aggregate()
.Match(childrenFilter)
.Group(c => c.ParentId, g => new KeyValuePair<string, List<Child>>(g.Key, new List<Child>(g)));
var groupCursor = await aggregation.ToCursorAsync();
然而,这会抛出
System.NotSupportedException: Could not find a member match for constructor parameter collection on type List`1.
几个小问题
我假设我已经
childrenFilter
以这样的方式编写了它,它会在服务器上执行并且客户端不会接收Gender.Female
孩子?如果那不是真的 - 正确的方法是什么?如果我将重载与Linq.Expression
- 一起使用,该过滤器会在服务器上还是在客户端上执行?孩子是在服务器上还是在客户端上分组?我应该如何编写
Group
才能使其在应该更有效的服务器上执行?
更新 17.06
根据@CraigWilson 的建议,我尝试过g.ToList()
:
var aggregation = children
.Aggregate()
.Match(childrenFilter)
.Group(c => c.ParentId, g => new KeyValuePair<string, List<Child>>(g.Key, g.ToList()));
这导致了一个不同的例外:
未处理的异常:System.AggregateException:发生一个或多个错误。--- System.InvalidCastException:无法将“MongoDB.Driver.Linq.Expressions.SerializationExpression”类型的对象转换为“System.Linq.Expressions.MethodCallExpression”类型。