如何使用Linq查询嵌套的动态BsonDocuments?

时间:2014-01-22 17:44:33

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

public class Foo
{
  public ObjectId _id { get; set; }
  public BsonDocument properties { get; set; }
}

public void FindFoos()
{
  var client = new MongoClient(ConfigurationManager.ConnectionStrings["MongoDB"].ConnectionString);
  var server = client.GetServer();
  var db = server.GetDatabase("FooBar");
  //var collection = db.GetCollection<GeoJsonFeature<GeoJson2DGeographicCoordinates>>("Sections");
  var collection = db.GetCollection<Foo>("Foos");



  collection.Insert(new Foo
  {
    properties = new BsonDocument{
                     {"Foo" , "foo1"},
                     {"Bar" , "bar1"}
                   }
  });
  collection.Insert(new Foo
  {
    properties = new BsonDocument{
                     {"Foo" , "foo2"},
                     {"Bar" , "bar2"}
                   }
  });


  var query = Query<Foo>.Where(foo => foo.properties.AsQueryable().Any(property => property.Name == "Foo" && property.Value.AsString == "foo1"));

  var result = collection.Find(query).First();
}  

调用FindFoos会导致以下异常:

不支持的where子句:Queryable.Any(Queryable.AsQueryable(foo.properties),(BsonElement属性)=&gt;((property.Name ==“Foo”)&amp;&amp;(property.Value.AsString == “foo1”)))。

描述:执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.ArgumentException:不支持where子句:Queryable.Any(Queryable.AsQueryable(foo.properties),(BsonElement属性)=&gt;((property.Name ==“Foo”)&amp;&amp;( property.Value.AsString ==“foo1”)))。

在这一行:

var query = Query<Foo>.Where(foo => foo.properties.AsQueryable().Any(property => property.Name == "Foo" && property.Value.AsString == "foo1"));

我可以在mongodb shell中轻松地执行此查询:

db.Foos.find( {'properties.Foo' : 'foo1'} );

使用Linq进行此查询的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

尝试使用LINQ的SelectMany()方法。它用于展平嵌套集合。我们可以用更“LINQ”的方式完成任务,而不是使用嵌套的for循环。

以下给出 -

Master m1 = new Master() { name = "A", lstObj = new List<obj> { new obj { i = 1, s = "C++" }, new obj { i = 1, s = "C#" }, new obj { i = 1, s = "Java" } } };

Master m2 = new Master() { name = "A", lstObj = new List<obj> { new obj { i = 4, s = "PHP" }, new obj { i = 5, s = "Ruby" }, new obj { i = 6, s = "Perl" } } };

List<Master> lstMasters = new List<Master> { m1, m2 };
var result = lstMasters.SelectMany(m => m.lstObj).Where(o => o.s == "PHP");

只需将Master课程替换为BsonDocument