我有一个名为'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'。
答案 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)。根据您的需求调整我的建议。