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

时间:2015-12-07 16:32:46

标签: c# mongodb linq mongodb-.net-driver

我有一个名为'Projects'的集合。 在每个项目中,我都有名为结构的子文档,其中包含另一个名为 StructureProperties 的子文档。

我希望通过'userId'获取属性,并使用C#驱动程序2.1 (用户ID) - 在每个属性子文档中找到它。

我的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; }
}

和最后一个StructureProperty:

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();

非常重要的是,我可以进行查询并获得良好的结果,但我得到了所有项目文档*所有是subDocuments **而不是获得具有特定结构和特定StructurePropery的项目(节点'ROOT'。

1 个答案:

答案 0 :(得分:0)

您是否只想返回根文档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();

或者,如果您想使用用户ID返回GeneralProject和单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();

我没有在真实数据库上测试它,我想,对于db中的大量数据,这些操作可能很复杂。但它基于您的数据库架构。

修改

根据你的意见:

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)。根据您的需求调整我的建议。