web-dev-qa-db-fra.com

Comment faire une insertion en bloc - Linq to Entities

Je ne trouve aucun exemple sur la façon de faire une insertion en vrac/batch à l'aide de Linq to Entities. Savez-vous comment faire un encart en vrac?

36
Luke101

Parfois, vous devez simplement mélanger des modèles. Utilisez peut-être SqlBulkCopy pour cette partie de votre référentiel (car cela se branche directement dans l'API de copie en bloc) et Entity Framework pour une partie du reste. Et si nécessaire, un peu d'ADO.NET direct. En fin de compte, l'objectif est de faire le travail.

22
Marc Gravell

Pour un exemple parfait de la façon de faire des insertions en masse avec LINQ to Entities, voir http://archive.msdn.Microsoft.com/LinqEntityDataReader . C'est un wrapper qui permet une utilisation facile de SqlBulkCopy.

@Marc Gravell est correct, parfois vous devez mélanger des modèles pour faire le travail.

12
Contango

J'ai écrit une classe qui insérera en vrac des entités EF (ou tout type d'objet tant que les noms de propriété correspondent aux noms de colonne).

La classe prend en charge la personnalisation de la taille du lot, les événements avant et après insertion, les insertions en file d'attente et le "mode Firehose" (donnez-lui un milliard d'objets, il respectera la taille du lot).

6
Ronnie Overby

Vous pouvez le faire en utilisant extension d'insertion en bloc

Il utilise SqlBulkCopy et un datareader personnalisé pour obtenir des performances maximales. En conséquence, il est plus de 20 fois plus rapide que l'utilisation de l'insertion régulière ou AddRange

Exemple d'utilisation de l'extension efbulkinsert:

context.BulkInsert(hugeAmountOfEntities);
3
maxlego

Pour insérer une énorme quantité de données dans une base de données, j'avais l'habitude de collecter toutes les informations d'insertion dans une liste et de convertir cette liste en DataTable. J'insère ensuite cette liste dans une base de données via SqlBulkCopy.

Où j'envoie ma liste générée
LiMyList
qui contient des informations sur toutes les données en masse que je souhaite insérer dans la base de données
et le transmettre à mon opération d'insertion en bloc

InsertData(LiMyList, "MyTable");

InsertData est

 public static void InsertData<T>(List<T> list,string TabelName)
        {
                DataTable dt = new DataTable("MyTable");
                clsBulkOperation blk = new clsBulkOperation();
                dt = ConvertToDataTable(list);
                ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
                using (SqlBulkCopy bulkcopy = new SqlBulkCopy(ConfigurationManager.ConnectionStrings["SchoolSoulDataEntitiesForReport"].ConnectionString))
                {
                    bulkcopy.BulkCopyTimeout = 660;
                    bulkcopy.DestinationTableName = TabelName;
                    bulkcopy.WriteToServer(dt);
                }
        }    

public static DataTable ConvertToDataTable<T>(IList<T> data)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
            DataTable table = new DataTable();
            foreach (PropertyDescriptor prop in properties)
                table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
            foreach (T item in data)
            {
                DataRow row = table.NewRow();
                foreach (PropertyDescriptor prop in properties)
                    row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                table.Rows.Add(row);
            }
            return table;
        }
2
Amit Bisht