2017-09-27 107 views
0

如果我有对象,让我们给他们打电话,有一些其他对象的名单集团我将其称之为品牌,这个对象有一个名为模式对象的列表。MongoDB的C#连续驱动的SelectMany

有没有办法只使用MongoDb c#驱动程序获得型号列表列表。

我试过用SelectMany多次但没有成功。如果我把多个SelectMany我总是得到一个空的列表。

代码应该是不言自明的。 最后是解释什么使我困惑的评论。

class Group 
{ 
    [BsonId(IdGenerator = typeof(GuidGenerator))] 
    public Guid ID { get; set; } 
    public string Name { get; set; } 
    public List<Brand> Brands { get; set; } 
} 

class Brand 
{ 
    public string Name { get; set; } 
    public List<Model> Models { get; set; } 
} 

class Model 
{ 
    public string Name { get; set; } 
    public int Produced { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     MongoClient client = new MongoClient("mongodb://127.0.0.1:32768"); 
     var db = client.GetDatabase("test"); 
     var collection = db.GetCollection<Group>("groups"); 

     var fca = new Group { Name = "FCA" }; 

     var alfaRomeo = new Brand { Name = "Alfra Romeo" }; 
     var jeep = new Brand { Name = "Jeep" }; 
     var ferrari = new Brand { Name = "Ferrari"}; 

     var laFerrari = new Model { Name = "LaFerrari", Produced = 4 }; 

     var wrangler = new Model { Name = "Wrangler", Produced = 3 }; 
     var compass = new Model { Name = "Compass", Produced = 8 }; 

     var giulietta = new Model { Name = "Giulietta", Produced = 7 }; 
     var giulia = new Model { Name = "Giulia", Produced = 8 }; 
     var _4c = new Model { Name = "4C", Produced = 6 };   

     fca.Brands = new List<Brand> { ferrari, alfaRomeo, jeep }; 

     ferrari.Models = new List<Model> { laFerrari }; 
     jeep.Models = new List<Model> { wrangler, compass }; 
     alfaRomeo.Models = new List<Model> { giulietta, giulia, _4c }; 

     collection.InsertOne(fca);     

     Console.WriteLine("press enter to continue"); 
     Console.ReadLine(); 

     var models = collection.AsQueryable().SelectMany(g => g.Brands).SelectMany(b => b.Models).ToList(); 
     Console.WriteLine(models.Count); //returns 0 I expected 6 
     Console.ReadLine(); 

    } 
} 
+1

的SelectMany似乎在你的代码确定

aggregate([{ "$unwind": "$Brands" }, { "$project": { "Brands": "$Brands", "_id": 0 } }, { "$project": { "Models": "$Brands.Models", "_id": 0 } }, { "$unwind": "$Models" }, { "$project": { "Models": "$Models", "_id": 0 } }]) 

OP输出。数据保存到数据库?尝试var models = collection.AsQueryable()。SelectMany(g => g.Brands).ToList()。SelectMany(b => b.Models).ToList(); – Mate

+0

@Mate数据保存到DB中。你的代码有效,但我不想那样使用它。因为在那种情况下,第二个SelectMany在C#虚拟机上做的工作不在数据库引擎中,因为它应该也使用更多的流量 – topolm

+0

好吧我理解,请检查您的C#驱动程序版本并阅读** MongoQueryable.SelectMany ** – Mate

回答

1

尝试

var models = collection.AsQueryable() 
.SelectMany(g => g.Brands) 
.Select(y => y.Models) 
.SelectMany(x=> x); 

Console.WriteLine(models.Count()); 

工作输出(额外选择()),而无需额外的选择()

aggregate([{ 
    "$unwind": "$Brands" 
}, { 
    "$project": { 
     "Brands": "$Brands", 
     "_id": 0 
    } 
}, { 
    "$unwind": "$Models" 
}, { 
    "$project": { 
     "Models": "$Models", 
     "_id": 0 
    } 
}]) 
+0

感谢这工作。您能否详细解释为什么有必要在两个SelectMany之间使用Select?这绝对是一个不同于System.Linq的行为。 – topolm

+1

@topolm太棒了!老实说,我不知道为什么。我已经与“最受欢迎”的ORM一起工作,并且他们都在SelectMany()翻译中遇到了一些问题。 通常解决方案是一样的,验证输出查询。 无论如何,我会尽力了解更多。 请检查更新。那里很清楚 – Mate