C# MongoDB LINQ连接集合属性类型的属性
我有以下类,它们通过MongoDb持久化:C# MongoDB LINQ连接集合属性类型的属性,c#,mongodb,linq,mongodb-.net-driver,C#,Mongodb,Linq,Mongodb .net Driver,我有以下类,它们通过MongoDb持久化: public class TypeA { public string Name { get; set; } public List<TypeB> Children { get; set; } } public class TypeB { public string Colour { get; set; } } 我加入了两个TypeA系列,如下所示: IQueryable<TypeA> collecti
public class TypeA
{
public string Name { get; set; }
public List<TypeB> Children { get; set; }
}
public class TypeB
{
public string Colour { get; set; }
}
我加入了两个TypeA系列,如下所示:
IQueryable<TypeA> collection1 = GetCollection();
IQueryable<TypeA> collection2 = GetCollection();
var query = from a in collection1
join b in collection2
on a.Name equals b.Name
select new { a.Name };
var list = query.ToList();
var letDef = BsonDocument.Parse("{ colA_Children: '$Children' }");
var filter = new BsonDocumentFilterDefinition<TypeA>(BsonDocument.Parse("{ $expr: { $setEquals: [ '$$colA_Children', '$Children' ] } }"));
var pipeline = new PipelineStagePipelineDefinition<TypeA, TypeA>(
new IPipelineStageDefinition[]
{
PipelineStageDefinitionBuilder.Match(filter),
});
var fieldDef = new ExpressionFieldDefinition<AggResult, List<TypeA>>(f => f.Matched);
var results = col1.Aggregate()
.Lookup<TypeA, TypeA, List<TypeA>, AggResult>(
foreignCollection: col2,
let: letDef,
lookupPipeline: pipeline,
@as: fieldDef
).ToList();
除了颜色属性的子属性集合之外,我如何做类似的事情
我尝试了以下方法,但MongoDb Linq驱动程序显然不喜欢join子句中的SelectMany语句:
IQueryable<TypeA> collection1 = GetCollection();
IQueryable<TypeA> collection2 = GetCollection();
var query = from a in collection1.SelectMany(a => a.Children)
join b in collection2.SelectMany(b => b.Children)
on a.Colour equals b.Colour
select new { a.Colour };
var list = query.ToList();
LINQ不是此类操作的前进道路,因为驱动程序无法将此类语法转换为MongoDB的聚合框架 您需要使用的管道阶段是,它允许您指定自定义连接条件。在这种情况下,您需要或。您的C代码可以如下所示:
IQueryable<TypeA> collection1 = GetCollection();
IQueryable<TypeA> collection2 = GetCollection();
var query = from a in collection1
join b in collection2
on a.Name equals b.Name
select new { a.Name };
var list = query.ToList();
var letDef = BsonDocument.Parse("{ colA_Children: '$Children' }");
var filter = new BsonDocumentFilterDefinition<TypeA>(BsonDocument.Parse("{ $expr: { $setEquals: [ '$$colA_Children', '$Children' ] } }"));
var pipeline = new PipelineStagePipelineDefinition<TypeA, TypeA>(
new IPipelineStageDefinition[]
{
PipelineStageDefinitionBuilder.Match(filter),
});
var fieldDef = new ExpressionFieldDefinition<AggResult, List<TypeA>>(f => f.Matched);
var results = col1.Aggregate()
.Lookup<TypeA, TypeA, List<TypeA>, AggResult>(
foreignCollection: col2,
let: letDef,
lookupPipeline: pipeline,
@as: fieldDef
).ToList();
其中:
[BsonIgnoreExtraElements]
public class AggResult : TypeA
{
public List<TypeA> Matched { get; set; }
}
col1.Aggregate似乎没有包含0个参数的重载。应该使用哪种重载?为什么Aggressult应该从TypeA继承?@User48591您不需要继承,只需要拥有与TypeA相同的字段和一个连接的实体列表。这里是我正在使用的聚合:我看到重载在MongoCollection上,而不是在IQueryable接口上。为了更好地理解您所写的内容,我还阅读了一些mongodb操作。我看到你给出的过滤器是在集合本身上,而不是在每个子类型的颜色属性上。我希望输出为类型B,即在匹配上child@User48591您可以将其更改为{$expr:{$setEquals:['$$colA_Children.color','$Children.color']}},然后将对字符串列表而不是对象列表执行set运算符,但在您的示例中,它是等效的,因为您只有一个属性。改写:$setEquals同时处理对象和字符串