问题描述:

Consider the following simple example of Students and Teachers;

// person

public class Person

{

public ObjectId Id { get; set; }

public string Name { get; set; }

public Person() {

Id = ObjectId.GenerateNewId(DateTime.Now);

}

}

// student has a Classroom

public class Student : Person

{

public string Classroom { get; set; }

}

// teacher has a Dictionary<ObjectId, Student> Students

public class Teacher : Person

{

[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfDocuments)]

public Dictionary<ObjectId, Student> Students { get; set; }

public Teacher() {

Students = new Dictionary<ObjectId, Student>();

}

}

class Program

{

static void Main(string[] args)

{

var server = MongoServer.Create("mongodb://localhost/database?safe=true");

var database = server.GetDatabase("sandbox");

var collection = database.GetCollection<Teacher>("teachers");

collection.Drop();

// create students

var s1 = new Student() { Name = "s1", Classroom = "foo" };

var s2 = new Student() { Name = "s2", Classroom = "foo" };

var s3 = new Student() { Name = "s3", Classroom = "baz" };

var s4 = new Student() { Name = "s4", Classroom = "foo" };

// teacher 1

var t1 = new Teacher() { Name = "t1" };

t1.Students.Add(s1.Id, s1);

t1.Students.Add(s2.Id, s2);

collection.Insert(t1);

// teacher 2

var t2 = new Teacher {Name = "t2"};

t2.Students.Add(s3.Id, s3);

collection.Insert(t2);

// add teacher 3

var t3 = new Teacher() {Name = "t3"};

t3.Students.Add(s4.Id, s4);

collection.Insert(t3);

// select via key

var onlyt1 = collection.AsQueryable().Where(t => t.Students.ContainsKey(s1.Id)).ToList();

Console.WriteLine("onlyt1 : {0}", onlyt1.ToJson());

Console.ReadLine();

}

}

I can select via the key (shown above), but how do I find all the teachers who have students with classroom of "foo"? I want to write something like;

// select via value

var shouldBeJustT1andT3 = collection.AsQueryable().Where(t => t.Students.Values.Where(s => s.Classroom == "foo")).ToList();

网友答案:

You can use Any to get any teacher for whom there are students in a given classroom "foo":

List<Teacher> shouldBeJustT1andT3 = collection.Where(
    teacher => teacher.Students.Any(student => student.Classroom == "foo")
).ToList(); 

Edit

Since Mongo's IQueryable isn't supporting Any by default, maybe you could just use Where and Count instead of Any:

List<Teacher> shouldBeJustT1andT3 = collection.Where(
    teacher => teacher.Students.Where(student => student.Classroom == "foo").Count() > 0
).ToList(); 
网友答案:

Can't you have Students of type just ICollection<Person>?

Then you don't need query dictionary's values but flat objects' list, i.e. where s.ID == x && s.Classroom == "blah".

Dictionary makes sense to find object by key only, i.e. t.Students[studentId].


To find teachers: see dbaseman's answer, he's correct.

相关阅读:
Top