通过C#驱动程序2.1查询嵌套类并返回MongoDB中的所有根文档
本文关键字:MongoDB 文档 返回 驱动程序 查询 嵌套 通过 | 更新日期: 2023-09-27 18:26:03
我有一个名为"Projects"的集合。在每个项目中,我都有名为Structures的子文档,其中包括另一个名为StructureProperties的子文档。
我希望通过"userId"获取属性,并使用C#驱动程序2.1获取它的ROOT(userId-在每个Properties子文档中都可以找到)。
我的Project类看起来是这样的:
public interface IGeneralProject
{
[BsonId]
ObjectId Id { get; set; }
string Name { get; set; }
List<GeneralStructure> GeneralStructures { get; set; }
}
[BsonKnownTypes(typeof(ProjectOne), typeof(ProjectTwo))]
public class GeneralProject : IGeneralProject
{
[BsonId]
public ObjectId Id { get; set; }
public string Name { get; set; }
public List<GeneralStructure> GeneralStructures { get; set; }
}
结构类别:
public interface IGeneralStrucute
{
ObjectId StructureId { get; set; }
string Name { get; set; }
List<GeneralStructureProperty> StructureProperties { get; set; }
}
[BsonKnownTypes(typeof(Structure), typeof(Houseware))]
public class GeneralStructure : IGeneralStrucute
{
public ObjectId StructureId { get; set; }
public string Name { get; set; }
public List<GeneralStructureProperty> StructureProperties { get; set; }
}
最后一个是结构属性:
public interface IGeneralStructureProperty
{
string Name { get; set; }
ObjectId UserId { get; set; }
}
[BsonKnownTypes(typeof(Propery), typeof(Office))]
public class GeneralStructureProperty
{
public string Name { get; set; }
public ObjectId UserId { get; set; }
}
我试过LINQ对此进行查询,但被卡住了。。。
以下是我的一些尝试:
1.
return (from project in projectCollection.AsQueryable()
from generalStructure in project.GeneralStructures
from generalStructureProperty in generalStructure.StructureProperties
where generalStructureProperty.UserId == ObjectId.Parse(userId)
select new GeneralProject()
{
Id = project.Id, Name = project.Name, GeneralStructures = new List<GeneralStructure>()
{
new GeneralStructure()
{
StructureId = generalStructure.StructureId, Name = generalStructure.Name, StructureProperties = new List<GeneralStructureProperty>()
{
new GeneralStructureProperty()
{
Name = generalStructureProperty.Name, UserId = generalStructureProperty.UserId
}
}
}
}
}).ToList();
2.
var query = from project in projectCollection.AsQueryable()
from structure in project.GeneralStructures
from structureProperty in structure.StructureProperties
where structureProperty.UserId == ObjectId.Parse(userId)
select // where I got stuck...
3.
var query =
projectCollection.AsQueryable()
.Select(project => project)
.Where(
project =>
project.GeneralStructures.Any(
structure =>
structure.StructureProperties.Any(
property => property.UserId == ObjectId.Parse(userId)))).ToList();
很重要的一点是,我可以进行查询并获得良好的结果,但我得到的是带有*all-is-subDocuments**的所有项目文档,而不是带有特定结构和特定结构权限(节点的"ROOT")的项目。
是否只返回根文档GeneralProject
(如主题中所述)?你可以试试这个:
var collection = mongoContext.GetCollection<GeneralProject>(); //your implementation here
var result = await collection
.Find(x => x.GeneralStructures.Any(y => y.StructureProperties.Any(z => z.UserId == {user id here})))
.FirstOrDefaultAsync();
或者,如果你想返回GeneralProject
和带有用户id的单个GeneralStructureProperty
,你可以尝试动态投影:
var result = await collection
.Find(x => x.GeneralStructures.Any(y => y.StructureProperties.Any(z => z.UserId == {user id here})))
.Project(
p => new
{
GeneralStructureProperty = p.GeneralStructures.FirstOrDefault(x => x.StructureProperties.Any(z => z.UserId == {user id here})),
GeneralProject = p
})
.FirstOrDefaultAsync();
我没有在真实的数据库上测试它,我想,对于数据库中的大量数据,这些操作可能会很复杂。但它基于您的数据库架构。
编辑:
根据您的意见:
var result = await collection
.Find(x => x.GeneralStructures.Any(y => y.StructureProperties.Any(z => z.UserId == ObjectId.Parse(userId))))
.Project(
p => new
{
Id = p.Id,
Name = p.Name,
Structure = p.GeneralStructures.FirstOrDefault(x => x.StructureProperties.Any(z => z.UserId == ObjectId.Parse(userId)))
})
.FirstOrDefaultAsync();
result.Structure.StructureProperties = result.Structure.StructureProperties.Where(x => x.UserId == ObjectId.Parse(userId)).ToList();
现在,您应该检索项目id、项目名称和具有属性的结构(具有预期的userId)。根据你的需要调整我的建议。