通过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")的项目。

通过C#驱动程序2.1查询嵌套类并返回MongoDB中的所有根文档

是否只返回根文档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)。根据你的需要调整我的建议。