2011-01-04 18 views
18

sto usando MongoDB e pilota ufficiale C# 0.9MongoDB: ID generati automaticamente sono zeri

Sto solo controllando come incorporare documenti semplici funziona.

ci sono 2 classi facile:

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; } 
} 

creo un nuovo utente:

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

collection.Insert(user.ToBsonDocument()); 

L'utente viene salvato con successo, lo è anche il suo indirizzo.

Dopo aver digitato

db.users.find() 

in guscio MongoDB, ho ottenuto il seguente risultato:

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

Perché indirizzo oggetto id 0?

Facendo query con l'indirizzo funziona però:

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

Si riporta l'utente "Sam". attributo

+0

faccio un'ipotesi: se si inserisce un'altra riga e si recupera la nuova riga l'ID è ancora 000000000000 – cristian

+0

@ Octopus-Paul, sì è corretto. – Alex

risposta

8

Uso BsonId:

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

Identificare il campo ID o la proprietà

per identificare quale campo o la proprietà di una classe è l'Id si può scrivere:

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

Driver Tutorial

Modifica

In realtà non funziona. Controllerò più tardi perché. Se avete bisogno di farlo funzionare uso seguente:

[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

Grazie per la risposta, ma ottengo ancora gli zeri ... – Alex

+1

okay fammi controllare. –

+0

Sembra un bug del driver. –

24

Non è tanto un problema come un caso di aspettative non soddisfatte. Solo al livello superiore _id viene automaticamente assegnato un valore. Eventuali _id incorporati devono essere assegnati valori dal codice client (utilizzare ObjectId.GenerateNewId). È anche possibile che tu non abbia nemmeno bisogno di un ObjectId nella classe Address (qual è lo scopo di questo?).

+0

Oh, ho sempre pensato che ObjectIds fosse obbligatorio per tutti i documenti. Se va bene non avere id tutto, allora è grandioso. Non chiamerei aspettative insoddisfatte, perché, ad esempio, il driver Ruby crea ID per documenti incorporati. – Alex

+1

Questo documento è documentato da qualche parte? Non ho visto alcuna menzione. Qual è la logica alla base dell'assegnazione automatica della root, ma non dei documenti con l'embed (pensavo che fossero tutti "documenti")? – UpTheCreek

+0

Inoltre, qualsiasi modo di utilizzare il generatore di GUID Comb in questo modo? – UpTheCreek

2

Prendi la collezione come Tipo di utente:

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

Inizializzare il _id campo come segue:

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

Poi si inserisce l'oggetto:

collection.InsertOne(user); 

Il campo _id verrà automaticamente essere generato.

In questo link troverete modi alternativi per avere ID auto-generati personalizzati.

Problemi correlati