2011-01-04 7 views
18

Ich MongoDB und offiziellen C# Treiber unter Verwendung von 0,9MongoDB: automatisch generierte IDs sind Nullen

Ich bin nur überprüft, wie einfach Dokumente einbetten funktioniert.

Es gibt zwei einfache Klassen:

public class User 
{ 
    public ObjectId _id { get; set; } 
    public string Name { get; set; } 
    public IEnumerable<Address> Addresses { get;set; } 
} 

public class Address 
{ 
    public ObjectId _id { get; set; } 
    public string Street { get; set; } 
    public string House { get; set; } 
} 

ich einen neuen Benutzer:

var user = new User 
{ 
    Name = "Sam", 
    Addresses = (new Address[] { new Address { House = "BIGHOUSE", Street = "BIGSTREET" } }) 
}; 

collection.Insert(user.ToBsonDocument()); 

Der Benutzer erfolgreich gespeichert wird, so dass seine Adresse ist.

Nach

db.users.find() 

in MongoDB Shell eingeben, bekam ich folgendes Ergebnis:

{ "_id" : ObjectId("4e572f2a3a6c471d3868b81d"), "Name" : "Sam", "Addresses" : [ 
     { 
       "_id" : ObjectId("000000000000000000000000"), 
       "Street" : "BIGSTREET", 
       "House" : "BIGHOUSE" 
     } 
] } 

Warum ist die Adresse Objekt-ID: 0? obwohl

Abfragen mit der Adresse Doing funktioniert:

collection.FindOne(Query.EQ("Addresses.Street", streetName)); 

Es gibt den Benutzer "Sam".

+0

Ich mache eine Annahme: Wenn Sie eine andere Zeile einfügen, und Sie die neue Zeile abrufen, ist die ID immer noch 000000000000 – cristian

+0

@ Octopus-Paul, ja das ist richtig. – Alex

Antwort

8

Verwenden BsonId Attribut:

public class Address 
{ 
    [BsonId] 
    public string _id { get; set; } 
    public string Street { get; set; } 
    public string House { get; set; } 
} 

Identifizierung des Id Feld oder eine Eigenschaft

, die dieses Feld oder das Eigentum von eine Klasse zu identifizieren ist die Id können Sie schreiben:

public class MyClass { 
    [BsonId] 
    public string SomeProperty { get; set; } 
} 

Driver Tutorial

bearbeiten

Es funktioniert eigentlich nicht. Ich werde später prüfen, warum. Wenn Sie bekommen es Gebrauch arbeiten folgende:

[Test] 
    public void Test() 
    { 
     var collection = Read.Database.GetCollection("test"); 

     var user = new User 
     { 
      Name = "Sam", 
      Addresses = (new Address[] { new Address { House = "BIGHOUSE", Street = "BIGSTREET", _id = ObjectId.GenerateNewId().ToString() } }) 
     }; 

     collection.Insert(user.ToBsonDocument()); 
    } 
+0

Danke für die Antwort, aber ich bekomme immer noch Nullen ... – Alex

+1

Okay lass mich überprüfen. –

+0

Sieht aus wie Treiberfehler. –

24

Es ist nicht so sehr ein Problem als ein Fall von unerfüllten Erwartungen. Nur der obersten Ebene _id wird automatisch ein Wert zugewiesen. Allen eingebetteten _ids sollten Werte vom Client-Code zugewiesen werden (verwenden Sie ObjectId.GenerateNewId). Es ist auch möglich, dass Sie nicht einmal eine ObjectId in der Address-Klasse benötigen (was ist der Zweck?).

+0

Oh, ich dachte immer, dass ObjectIds für alle Dokumente obligatorisch sind. Wenn es okay ist, keine ID zu haben, dann ist es großartig. Ich würde es nicht als unerfüllte Erwartungen bezeichnen, da zum Beispiel der Ruby-Treiber IDs für eingebettete Dokumente erstellt. – Alex

+1

Ist das irgendwo dokumentiert? Ich habe keine Erwähnung davon gesehen. Was ist der Grund für die automatische Zuweisung der root-, aber nicht bearbeiteten Dokumente (ich dachte, sie wären alle 'Dokumente')? – UpTheCreek

+0

Kann man den Kamm-GUID-Generator auf diese Weise benutzen? – UpTheCreek

2

die Sammlung als Benutzertyp Get:

var collection = db.GetCollection<User>("users"); 

das Feld _id initialisieren wie folgt:

collection.InsertOne(user); 

Das _id Feld automatisch wird:

das Objekt einfügen Sie
var user = new User 
{ 
    _id = ObjectId.Empty, 
    Name = "Sam", 
    Addresses = (new Address[] { new Address { House = "BIGHOUSE", Street = "BIGSTREET" } }) 
}; 

Dann erzeugt werden.

In diesem link finden Sie alternative Möglichkeiten, benutzerdefinierte automatisch generierte ID (s) zu haben.