Linq to Sql: Cómo limpiar rápidamente una mesa

88

Para eliminar todas las filas de una tabla, actualmente estoy haciendo lo siguiente:

context.Entities.DeleteAllOnSubmit(context.Entities);
context.SubmitChanges();

Sin embargo, esto parece estar tardando años. ¿Hay una manera mas rápida?

Svish
fuente
¿Alguna razón por la que no está utilizando un proceso almacenado para una eliminación más rápida y segura? Puede hacer que el proceso se asigne a dbml
Perpetualcoder
1
¿No tendrías entonces que hacer uno para cada mesa? ¿O?
Svish

Respuestas:

126

Puede hacer un comando SQL normal para truncar o eliminar, utilizando el método DataContext.ExecuteCommand :

context.ExecuteCommand("DELETE FROM Entity");

O

context.ExecuteCommand("TRUNCATE TABLE Entity");

La forma en que está eliminando está tardando mucho porque Linq to SQL genera una declaración DELETE para cada entidad , hay otros enfoques seguros para realizar eliminaciones / actualizaciones por lotes, consulte los siguientes artículos:

Christian C. Salvadó
fuente
asegúrese de corregir la palabra "BORRAR"
David
9
Hice +1 en esto. Aquí hay una referencia que explica la diferencia entre Truncar (que creo que desea hacer) y Eliminar: mssqltips.com/tip.asp?tip=1080
David
1
+1 en el comentario de David: truncar puede ser mucho más rápido que eliminar
Fredrik Mörk
1
@David: Ese problema es específico del Entity Framework ( Linq-to-Entities ), lo he usado TRUNCATEantes sin problemas en Linq-to-SQL
Christian C. Salvadó
1
TRUNCATE eliminará cualquier indexación automática que se haya establecido (normalmente una columna de Id), así que tenga cuidado si no desea que se restablezca. DELETE FROM no lo hará.
JCisar
20

Desafortunadamente, LINQ-to-SQL no ejecuta muy bien las consultas basadas en conjuntos.

Asumirías que

context.Entities.DeleteAllOnSubmit(context.Entities); 
context.SubmitChanges(); 

se traducirá en algo como

DELETE FROM [Entities]

pero desafortunadamente es más como

DELETE FROM [dbo].[Entities] WHERE ([EntitiesId] = @p0) AND ([Column1] = @p1) ...
DELETE FROM [dbo].[Entities] WHERE ([EntitiesId] = @p0) AND ([Column1] = @p1) ...
DELETE FROM [dbo].[Entities] WHERE ([EntitiesId] = @p0) AND ([Column1] = @p1) ...

Encontrará lo mismo cuando intente realizar una actualización masiva en LINQ-to-SQL. Más de unos pocos cientos de filas a la vez y simplemente será demasiado lento.

Si necesita realizar operaciones por lotes y está utilizando LINQ-to-SQL, debe escribir procedimientos almacenados.

Kirk Broadhurst
fuente
12

Me gusta usar un método de extensión, según lo siguiente:

public static class LinqExtension
{
  public static void Truncate<TEntity>(this Table<TEntity> table) where TEntity : class
  {
    var rowType = table.GetType().GetGenericArguments()[0];
    var tableName = table.Context.Mapping.GetTable(rowType).TableName;
    var sqlCommand = String.Format("TRUNCATE TABLE {0}", tableName);
    table.Context.ExecuteCommand(sqlCommand);
  }
}
Bill Roberts
fuente
0

también puedes usar esto:

Public void BorraFilasTabla()
{
 using(basededatos db = new basededatos())
 {
  var ListaParaBorrar = db.Tabla.Tolist();
  db.Tabla.RemoveRange(ListaParaBorrar); 
 }
}
Gerardo Guajardo
fuente
La pregunta es: "¿Existe una forma más rápida?". ¿Cómo sería esto más rápido? Además, esto no es LINQ to SQL.
Gert Arnold
-1

El siguiente código c # se usa para Insertar / Actualizar / Eliminar / DeleteAll en una tabla de base de datos usando LINQ to SQL

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace PracticeApp
{
    class PracticeApp
    {        
        public void InsertRecord(string Name, string Dept) {
            LinqToSQLDataContext LTDT = new LinqToSQLDataContext();
            LINQTOSQL0 L0 = new LINQTOSQL0 { NAME = Name, DEPARTMENT = Dept };
            LTDT.LINQTOSQL0s.InsertOnSubmit(L0);
            LTDT.SubmitChanges();
        }

        public void UpdateRecord(int ID, string Name, string Dept)
        {
            LinqToSQLDataContext LTDT = new LinqToSQLDataContext();
            LINQTOSQL0 L0 = (from item in LTDT.LINQTOSQL0s where item.ID == ID select item).FirstOrDefault();
            L0.NAME = Name;
            L0.DEPARTMENT = Dept;
            LTDT.SubmitChanges();
        }

        public void DeleteRecord(int ID)
        {
            LinqToSQLDataContext LTDT = new LinqToSQLDataContext();
            LINQTOSQL0 L0;
            if (ID != 0)
            {
                L0 = (from item in LTDT.LINQTOSQL0s where item.ID == ID select item).FirstOrDefault();
                LTDT.LINQTOSQL0s.DeleteOnSubmit(L0);
            }
            else
            {
                IEnumerable<LINQTOSQL0> Data = from item in LTDT.LINQTOSQL0s where item.ID !=0 select item;
                LTDT.LINQTOSQL0s.DeleteAllOnSubmit(Data);
            }           
            LTDT.SubmitChanges();
        }

        static void Main(string[] args) {
            Console.Write("* Enter Comma Separated Values to Insert Records\n* To Delete a Record Enter 'Delete' or To Update the Record Enter 'Update' Then Enter the Values\n* Dont Pass ID While Inserting Record.\n* To Delete All Records Pass 0 as Parameter for Delete.\n");
            var message = "Successfully Completed";
            try
            {
                PracticeApp pa = new PracticeApp();
                var enteredValue = Console.ReadLine();                
                if (Regex.Split(enteredValue, ",")[0] == "Delete") 
                {
                    Console.Write("Delete Operation in Progress...\n");
                    pa.DeleteRecord(Int32.Parse(Regex.Split(enteredValue, ",")[1]));
                }
                else if (Regex.Split(enteredValue, ",")[0] == "Update")
                {
                    Console.Write("Update Operation in Progress...\n");
                    pa.UpdateRecord(Int32.Parse(Regex.Split(enteredValue, ",")[1]), Regex.Split(enteredValue, ",")[2], Regex.Split(enteredValue, ",")[3]);
                }
                else
                {
                    Console.Write("Insert Operation in Progress...\n");
                    pa.InsertRecord(Regex.Split(enteredValue, ",")[0], Regex.Split(enteredValue, ",")[1]);
                }                                
            }
            catch (Exception ex)
            {
                message = ex.ToString();
            }
            Console.Write(message);            
            Console.ReadLine();                        
        }
    }
}

fuente
1
agregue alguna explicación
Yahya Hussein