2010-11-01 20 views
1

J'ai un tas de code qui est configuré pour ajouter des insertions de 10k à 20k à une base de données LINQ en plus de quelques mises à jour/suppressions. Toutes ces modifications sont validées via un appel db.SubmitChanges(). Le problème est qu'il est trop lent :( La performance a été soigneusement testé dans ce grand poste sur StackOverflow:Détection des insertions LINQ Avant de soumettre des modifications et d'utiliser BulkInsert à la place

Very slow insert process using Linq to Sql

Le problème est que je ne veux pas réécrire tout le code qui prépare mon DB . objet que j'ai essayé de code psuedo ce que je voudrais faire ci-dessous

Avertissement:. Ce n'est pas vrai code Il ne compilera pas .... même pas près :)

VIEUX! WAY:

SchedDB.Data.SchedulerDBDataContext db = new SchedDB.Data.SchedulerDBDataContext(); 
//Do a bunch of stuff to populate "db" 
db.SubmitChanges() 

NOUVELLE FAÇON:

SchedDB.Data.SchedulerDBDataContext db = new SchedDB.Data.SchedulerDBDataContext(); 
//Do a bunch of stuff to populate "db" 
//NEW: Detect all of the inserts in the "db" object. Remove those inserts and generate code to insert them with a batch dataadapter. For example: 
// 
//DataTable dtProducts = new DataTable() 
//dtProducts.Columns.Add(ProductID) //yada yada all of the columns here 
// 
//DataTable dtCustomers = new DataTable() 
//dtCustomers.Columns.Add(CustomerID) //yada yada all of the columns here 


//foreach (insertItem in db.Inserts) //this is pseudo code, I need help here 
//{ 
// if (insertItem.destinationTable == "Products") 
// { 
//  DataRow dr = dtProducts.NewRow(); 
//  dr["ProductID"] = insertItem.ProductID; //This line of code probably isn't even close to being right... I can't imagine the "insertItem" holding all of the columns no matter what the destinationTable is 
// } 
// if (insertItem.destinationTable == "Customers") 
// { 
//  //similar code, all customer columns, yada yada 
// } 
// IMPORTANT: remove the item from the LINQ db so it doesn't insert it anymore 
// 
// Make a table adapter for each datatable 
// Set the .BatchSize parameter 
//Commit each table adapter. 
// db.SubmitChanges() //If there are any updates or deletes they are still in here and still need to happen. 

S'il y a des erreurs dans les mises à jour de masse, alors il serait bon de savoir que pour que je puisse faire reculer le db LINQ et potentiellement exécuter un autre code pour effacer les inserts de dataapapters. (Je peux gérer cela, tous mes inserts ont une colonne supplémentaire qui est un int qui est unique à l'insertion par lots.)

Répondre

0

Au lieu de tout cela, pourquoi ne pas simplement insérer db.SubmitChanges(); appels après chaque élément individuel, ou après des blocs de X éléments? Ce n'est pas idéal non plus, mais mieux que de soumettre des changements massifs en même temps, et potentiellement très facile à changer dans le code.

Alimentez les mises à jour de taille moyenne DataContext, et cela ne vous gêne pas vraiment. Puis passez à des choses plus productives.

+1

1. Le code de remplissage de l'objet LINQ db est réparti sur plusieurs zones et est trop dispersé pour commencer à modifier partout. Je dois être capable d'opérer sur l'objet db entièrement peuplé. 2. Je pense toujours que la performance est mauvaise par rapport à l'article dont j'ai parlé. Je veux profiter de ce post car les inserts y sont extrêmement rapides. db.SubmitChanges() est un insert séparé pour chaque ligne. – Robert

+0

Eh bien, si vous ne pouvez pas apporter de changements significatifs au code, il y a probablement très peu de choses que vous pouvez faire. –