2017-09-27 8 views
0

Si j'ai des objets, permet de les appeler groupe qui a liste de quelques autres objets que je l'appellerai Marque, et cet objet a une liste d'objets appelés Modèle.MongoDB C# pilote SelectMany consécutif

Y at-il un moyen d'obtenir uniquement la liste des modèles en utilisant le pilote MongoDb C#.

J'ai essayé d'utiliser SelectMany plusieurs fois mais sans succès. Si je mets plus d'un SelectMany je reçois toujours une liste vide.

Le code doit être explicite. A la fin est un commentaire qui explique ce qui me trouble.

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 semble ok dans votre code . les données ont-elles été sauvegardées dans DB? Essayez var models = collection.AsQueryable(). SelectMany (g => g.Marques) .ToList(). SelectMany (b => b.Models) .ToList(); – Mate

+0

Les données @Mate sont enregistrées dans la base de données. Votre code fonctionne, mais je ne voudrais pas l'utiliser comme ça. Parce que dans ce cas deuxième SelectMany faire le travail sur C# machine virtuelle pas dans le moteur de base de données comme il le devrait et aussi utiliser plus de trafic – topolm

+0

ok je comprends, vérifiez votre version du pilote C# et lisez sur ** MongoQueryable.SelectMany ** – Mate

Répondre

1

Essayez

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

Console.WriteLine(models.Count()); 

Sortie de travail (avec Sélectionner la())

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

OP Sortie sans Sélectionner la()

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

Merci cela fonctionne. Pourriez-vous s'il vous plaît expliquer en plus de détails pourquoi il est nécessaire d'utiliser Select entre deux SelectMany? C'est certainement un comportement différent de celui de System.Linq. – topolm

+1

@topolm Super! Honnêtement, je ne sais pas pourquoi. J'ai travaillé avec les ORM les plus populaires et tous ont des problèmes avec la traduction de SelectMany(). Habituellement, la solution est la même, vérifiez la requête de sortie. En tout cas, je vais essayer d'en savoir plus à ce sujet. S'il vous plaît, vérifiez la mise à jour. C'est clair là – Mate