2011-10-08 15 views
16

Ho una classe User e ho bisogno di lavorare con loro nei servizi web.MongoDB C#: ID Serialization miglior pattern

Poi problema è che se provo a serializzare Id che tipo di BsonObjectId, vedo che hanno una proprietà vuota, che hanno una proprietà vuota, e così via ...

devo scrivere questa soluzione in ordine, è una buona soluzione?

public partial class i_User 
{ 
    [BsonId(IdGenerator = typeof(BsonObjectIdGenerator))] 
    [NonSerialized] 
    public BsonObjectId _id; 

    public String Id 
    { 
     get 
     { 
      return this._id.ToString(); 
     } 
    } 
} 

In questo modo, posso tenere _Id come BsonObjectId ma inviare una rappresentazione di stringa attraverso il web nella proprietà Id.

Un'altra soluzione è quella di lavorare con StringObjectIdGenerator

public partial class i_User 
{ 
    [BsonId(IdGenerator = typeof(StringObjectIdGenerator))] 
    public String id; 
} 

Ma è vedere che MongoDB memorizza un string nel database invece di ObjectId.

Qual è l'approccio migliore per lavorare in una serializzazione ambientale come servizi web e/o client-server (Flash + C#)?

risposta

90

Se ho capito bene, si desidera accedere alla proprietà Id come stringa, ma avere lo Id salvato come ObjectId in MongoDB. Questo può essere realizzato utilizzando BsonRepresentation con BsonId.

[BsonId] 
[BsonRepresentation(BsonType.ObjectId)] 
public string Id { get; set; } 

Dettagli possono essere trovati here.

+3

Grazie! Potrei votare per te due volte se potessi;) – Doobi

+1

hai appena salvato la mia giornata – emreturan

+1

Hai trascorso 2 ore a combattere una risposta webapi che non avrebbe serializzato un ObjectId non elaborato. Questo mi ha salvato probabilmente altre 2 ore –

6

Se si vuole fare con una mappa di classi - questo è il modo per farlo:

BsonClassMap.RegisterClassMap<i_User>(cm => 
{ 
    cm.AutoMap(); 
    cm.SetIdMember(cm.GetMemberMap(x => x.Id) 
    .SetIdGenerator(StringObjectIdGenerator.Instance)); 
}); 
+0

Questo è un modo molto carino in cui POCO rimane pulito, il che è la mia preoccupazione principale. Ma in realtà metterà l'id come stringa in Mongo. L'ideale sarebbe avere la rappresentazione di ObjectId nel database e la rappresentazione delle stringhe in POCO. È possibile? –

+0

Non che io sappia, ma suppongo che tu possa modificare il driver C#. Lo scopo dell'utilizzo di ObjectId richiede solo 12 byte e un timestamp di build. Perché non utilizzare ObjectId nelle entità del tuo dominio? – Lybecker

+1

Grazie per la risposta rapida. Solitamente voglio avere il mio livello di dominio indipendente dalla tecnica del livello di archiviazione. Ma immagino che tutto sia un compromesso. –

1

C'è anche un approccio più generico utilizzando convenzioni. Questo approccio consente di configurare le regole per tutti i modelli in un'unica posizione.

Primo. Aggiungi una convenzione per il generatore di ID

public class IdGeneratorConvention : ConventionBase, IPostProcessingConvention 
{ 
    public void PostProcess(BsonClassMap classMap) 
    { 
     var idMemberMap = classMap.IdMemberMap; 
     if (idMemberMap == null || idMemberMap.IdGenerator != null) 
     { 
      return; 
     } 

     idMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance); 
    } 
} 

Secondo. Registra la nostra convention. Il metodo Register deve essere chiamato prima della prima query.

var conventionPack = new ConventionPack { new IdGeneratorConvention() }; 
ConventionRegistry.Register("Pack", conventionPack, x => true);