2015-05-07 17 views
7

Sto testando MongoDB (server v 2.6.7) con il driver C# 2.0.MongoDB (server v 2.6.7) con C# driver 2.0: Come ottenere il risultato da InsertOneAsync

Quando sto usando la funzione di inserimento InsertOneAsync per un documento con un _id che esiste Mi aspetto un errore come quello che si ottiene dalla shell Mongo:

WriteResult({ 
    "nInserted" : 0, 
    "writeError" : { 
      "code" : 11000, 
      "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: mydb.Commands.$_id_ dup key: { : 0.0 }" 
    }}) 

Ma il problema è che l'inserto con il driver C# non genera un'eccezione e non riesco a trovare lo WriteResult per l'inserto. Quando guardo nel database sembra che non sia successo niente.

Quindi la mia domanda è cosa aspettarsi da InsertOneAsync quando si inserisce uno _id esistente?

Il codice in Visual Studio:

IMongoCollection<BsonDocument> commandsCollection = db.GetCollection<BsonDocument>("Commands"); 
var bson = new BsonDocument 
     { 
      {"_id", i.Value}, 
      {"label", i.Key} 
     }; 
commandsCollection.InsertOneAsync(bson); 

risposta

9

Se stai facendo questo all'interno di un async metodo, quindi la risposta di Brduca funzionerà (ed è preferibile), altrimenti è possibile chiamare Wait() su Task restituito dallo InsertOneAsync chiamata al fine di garantire l'applicazione rimane intorno abbastanza a lungo per vedere l'eccezione di chiave duplicata:

commandsCollection.InsertOneAsync(doc).Wait(); 

Se l'inserimento non riesce a causa di una chiave duplicata, la Wait() genera un AggregateException che contiene una MongoWriteException che contiene i dettagli chiave duplicate .

try 
{ 
    commandsCollection.InsertOneAsync(doc).Wait(); 
} 
catch(AggregateException aggEx) 
{ 
    aggEx.Handle(x => 
    { 
     var mwx = x as MongoWriteException; 
     if (mwx != null && mwx.WriteError.Category == ServerErrorCategory.DuplicateKey) 
     { 
      // mwx.WriteError.Message contains the duplicate key error message 
      return true; 
     } 
     return false; 
    }); 
} 

Allo stesso modo, se si sta utilizzando await, che genera un AggregateException pure.

Per evitare la complessità del AggregateException avvolgere l'eccezione mongo, è possibile chiamare GetAwaiter().GetResult() invece di Wait():

try 
{ 
    commandsCollection.InsertOneAsync(doc).GetAwaiter().GetResult(); 
} 
catch(MongoWriteException mwx) 
{ 
    if (mwx.WriteError.Category == ServerErrorCategory.DuplicateKey) 
    { 
     // mwx.WriteError.Message contains the duplicate key error message 
    } 
} 
+1

Ma come posso rilevare la chiave duplicata? InsertOneAsync restituirà un'attività senza parte risultato. E Wait restituirà un vuoto. – Fredrik

+1

Grazie. Solamente un'altra cosa. Come posso trovare le informazioni chiave duplicate in una MongoWriteException? 'catch (AggregateException e) { e.Handle ((x) => { se (x è MongoWriteException) {} return true; });' – Fredrik

+0

@Fredrik veda la risposta aggiornata. – JohnnyHK

2

Questo è un compito asincrona, vi state perdendo l'attendono

await commandsCollection.InsertOneAsync(bson); 

https://github.com/mongodb/mongo-csharp-driver/blob/master/README.md

+1

Okej, ho aggiunto l'attesa ma ora il programma C# termina tranquillamente dove è l'inserto.Voglio un'eccezione gettata in faccia ^^ – Fredrik

+0

hai provato a salvare esplicitamente la collezione? commandsCollection.Save() – Brduca

+1

Sfortunatamente tale comando non esiste nella nuova versione del driver C#. [collegamento] (http://stackoverflow.com/questions/29327856/how-to-insert-data-into-a-mongodb-collection-using-c) La seconda risposta. – Fredrik

1

A seguito @JonnyHK rispondere si può fare lo stesso quando si inseriscono molti.

collection.InsertManyAsync(doc, new InsertManyOptions { IsOrdered = false }).Wait(); 

sarebbe stato spostato in try/catch;

try 
{ 
    collection.InsertManyAsync(doc, new InsertManyOptions { IsOrdered = false }).Wait(); 
} 
catch (AggregateException aggEx) 
{ 
    aggEx.Handle(x => 
    { 
     var mwx = x as MongoBulkWriteException; 
     return mwx != null && mwx.WriteErrors.All(e => e.Category == ServerErrorCategory.DuplicateKey); 
    }); 
} 
0

Sto usando VS 2015 e provato tutto il modo per aggiungere dati utilizzando InsertOne/InsertOneAsync, ma nessuno di lavorare.

Codice: // Creare un oggetto MongoClient utilizzando la stringa di connessione _client = new MongoClient();

 //Use the MongoClient to access the server 
     _database = _client.GetDatabase("ratednext"); 

     //get mongodb collection 

     var Collec = _database.GetCollection<BsonDocument>("computers"); 
     var documnt = new BsonDocument 
     { 
      {"Brand","Dell"}, 
      {"Price","400"}, 
      {"Ram","8GB"}, 
      {"HardDisk","1TB"}, 
      {"Screen","16inch"} 
     }; 
     try 
     { 
      Collec.InsertOneAsync(documnt).GetAwaiter().GetResult(); 
     } 
     catch (AggregateException aggEx) 
     { 
      aggEx.Handle(x => 
      { 
       var mwx = x as MongoWriteException; 
       if (mwx != null && mwx.WriteError.Category == ServerErrorCategory.DuplicateKey) 
       { 
        // mwx.WriteError.Message contains the duplicate key error message 
        return true; 
       } 
       return false; 
      }); 
     } 
Problemi correlati