2012-12-17 2 views
0

d'une question précédente, je suis en train de faire une SqlBulkCopy à partir d'une base de données MongoDB, et je me fais une erreur et ne peut pas trouver quel type colonne je devrais avoir:En utilisant SqlBulkCopy avec MongoDB

La valeur donnée de type ObjectId de la source de données ne peut pas être convertie en type nvarchar de la colonne cible spécifiée.

enter image description here

Où ma DataTable colonne DataType est MongoDB.Bson.ObjectId.

Quel devrait être le type dans Microsoft Sql Server pour héberger cette valeur?

Mon code actuel:

string connectionString = GetDestinationConnectionString(); 
var mongoCollection = GetSourceConnectionString(); 

var queryFind = Query.And(Query.NotExists("sync"), Query.NotIn("challenge_guid", new List<MongoDB.Bson.BsonValue>() { "87558b59-73ee-4f10-add4-b9031551e395" })); 
var sourceData = mongoCollection.Find(queryFind).ToList(); 

DataTable dt = CollectionHelper.ConvertTo<MongoAnswerDoc>(sourceData); 

using (SqlConnection destinationConnection = 
      new SqlConnection(connectionString)) 
{ 
    destinationConnection.Open(); 

    // Set up the bulk copy object. 
    // Note that the column positions in the source 
    // data reader match the column positions in 
    // the destination table so there is no need to 
    // map columns. 
    using (SqlBulkCopy bulkCopy = 
       new SqlBulkCopy(destinationConnection)) 
    { 
     bulkCopy.DestinationTableName = "JK_RawChallengeAnswers"; 

     try 
     { 
      // Write from the source to the destination. 
      bulkCopy.WriteToServer(dt); 
     } 
     catch (Exception ex) 
     { 
      txtMsg.Text = ex.Message; 
     } 
     finally 
     { 
      // Dispose of the DataTable. 
      dt.Dispose(); 
      // close connection 
      destinationConnection.Close(); 
     } 
    } 
} 

Répondre

1

De l'Mongo spec:

ObjectId est un type BSON 12 octets, construit en utilisant:

  • un horodatage de 4 octets,
  • un identifiant de machine de 3 octets,
  • un ID de processus de 2 octets et
  • un compteur de 3 octets.

Donc, vous auriez besoin d'une colonne de type BINARY(12) à la carte dans SQL.

Quoi qu'il en soit, votre code manquera de mémoire lors de tout transfert de signification, l'utilisation d'une copie intermédiaire en mémoire de DataTable n'est pas la solution. EnableStreaming et utilisez un IDataReader pour parcourir la source juste à temps.

+0

Est-ce que je devrais convertir un 'Mongo.Cursor' (qui est la sortie de la requête) en un' IDataReader' sans créer un nouvel objet et l'implémenter? – balexandre

+0

Ce n'est pas difficile, vous avez seulement besoin d'une implémentation IDataReader très basique. Jetez un oeil à http://blogs.microsoft.co.il/blogs/aviwortzel/archive/2008/05/06/implementing-sqlbulkcopy-in-linq-to-sql.aspx –

+1

Plus d'exemples: http: // www .developerfusion.com/article/122498/using-sqlbulkcopy-for-high-performance-inserts /, http://www.csvreader.com/posts/generic_list_datareader.php –