2011-09-02 27 views
13

Tengo un problema al actualizar a mongo db utilizando el controlador oficial C#.Reposición en Mongo DB y el problema Id

public abstract class AggregateRoot 
{ 
    /// <summary> 
    /// All mongoDb documents must have an id, we specify it here 
    /// </summary> 
    protected AggregateRoot() 
    { 
     Id = ObjectId.GenerateNewId(); 
    } 

    [BsonId] 
    public ObjectId Id { get; set; } 
} 

Mis entidades ya tienen el id-s, pero tuve que crear el ID específico mongo para que funcione, ya que todos los documentos en una colección debe tener uno. Ahora, luego recibo una nueva entidad en mi sistema, se genera un nuevo Mongo Id y obtengo el mongo no puede cambiar _id de un documento antiguo excepción. ¿Hay algo de trabajo?

Déjame describir el diseño un poco. Todas las entidades que serían almacenadas como documentos heredaban de AggregateRoot que tenía la generación de id en él. Cada subdocumento tenía su identificación generada automáticamente y no tuve ningún problema con esto. La identificación en AggregateRoot se introdujo para corregir el problema al recuperar datos de MongoCollection a List y se introdujo la generación, por lo que los id-s son diferentes. Ahora podemos mover esa generación de id para guardar los métodos porque la nueva entidad para la actualización tenía una nueva generación de id. Pero significa que cada desarrollador del equipo no debe olvidar generar id-s en el repositorio, lo que es riesgoso. Que sería mejor simplemente ignorar el id de mapeo de mongo si es posible y no tener clase AggregateRoot en absoluto

+0

¿Cómo está guardando sus objetos? El atributo BsonId debe obligar a MongoDB a usar ese campo como tu id. –

+0

La idea es que los datos provienen de un sistema externo para el almacenamiento. Tiene su propio id-s que tengo que almacenar. Y esta es una identificación falsa por el bien de la compatibilidad de Mongo. Cada documento hereda de AggregateRoot, por lo que esto se genera al recibir cada objeto. Está claro que podría recibir los mismos datos, pero el id de mongo generado es diferente. Entonces aparece la excepción –

Respuesta

8

Parece que es posible que se configura explícitamente el valor Id para ambas inserciones y actualizaciones. Eso está bien para las inserciones, todos los objetos nuevos necesitan un valor de _id; sin embargo, para las actualizaciones no está permitido cambiar el valor de _id en un documento existente después de que se haya creado.

Intente no establecer el valor Id en absoluto. Si no especifica un valor antes de insertarlo, el controlador usa las clases incorporadas IdGenerator para generar un nuevo valor _id, por lo que si es un tipo ObjectId usará el ObjectIdGenerator. Entonces, tanto las inserciones como las actualizaciones funcionan bien.

+0

Si elimino la propiedad de identificación, entonces realmente no es un problema guardar/actualizar una entidad. El problema es que arroja una excepción cuando trato de buscar en la colección del código porque no puede asignar el _id a una propiedad inexistente –

+2

Puede usar el atributo '[BsonIgnoreExtraElements]' en la clase si la colección tiene campos que no lo hacen t tienen propiedades coincidentes. –

50

He encontrado un problema similar. Quería recuperar documentos con el controlador oficial C#. Tenía una clase como esta:

public class MyClass 
{ 
    public ObjectId Id { get; set; } 
    public int Field1 { get; set; } 
    public string Field2 { get; set; } 
} 

En la consola que iba a escribir: db.collection.update({Field1: 3},{Field1: 3, Field2: "value"}) y que iba a funcionar. En C# escribí:

collection.Update(Query.EQ("Field1", 3), 
       Update.Replace(new MyClass { Field1 = 3, Field2 = "value" }), 
       UpdateFlags.Upsert); 

y no funcionó! Porque el controlador incluye un ID vacío en la declaración de actualización y cuando inserto un segundo documento con un valor diferente de Field1, se lanza la excepción E11000 duplicate key error index (en este caso, Mongo intenta insertar un documento con _id que ya existe en db).

Cuando genero _id yo mismo (como tema de inicio) he encontrado la misma excepción (mongo cannot change _id of a document) en la inserción de objetos con el valor existente de Field1.

Solución es marcar la propiedad de Id. Por atributo [BsonIgnoreIfDefault] (y no inicializarlo). En este caso, el controlador omite el campo _id en la declaración de actualización y MongoDb genera Id si es necesario.

+8

Usted dictamina hombre, que [BsonIgnoreIfDefault] ahorró una tonelada de tiempo. Es una pena poder votar más por ti. –

+2

Perdí cerca de una hora tratando de descubrir por qué mi llamada a ReplaceOneAsync con el controlador 2.0 no funcionaba. Encontré esta respuesta. Se agregó [BsonIgnoreIfDefault] y el problema se resolvió. ¡Gracias! – BrandonLWhite

+1

He pasado horas tratando de resolver esto. ¡GRACIAS! – bbrez1

Cuestiones relacionadas