私はこの単純化されたモデルを持っています:
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: 1 つ以上のエラーが発生しました。--- System.InvalidCastException: タイプ 'MongoDB.Driver.Linq.Expressions.SerializationExpression' のオブジェクトをタイプ 'System.Linq.Expressions.MethodCallExpression' にキャストできません。