Linq para Sql: Como limpar rapidamente uma mesa

88

Para excluir todas as linhas de uma tabela, estou fazendo o seguinte:

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

No entanto, isso parece estar demorando muito. Existe uma maneira mais rápida?

Svish
fonte
Alguma razão pela qual você não está usando um procedimento armazenado para uma exclusão mais rápida e segura? Você pode ter o proc mapeado em dbml
Perpetualcoder
1
Você não teria que fazer um para cada mesa então? Ou?
Svish,

Respostas:

126

Você poderia fazer um comando SQL truncate ou delete normal, usando o método DataContext.ExecuteCommand :

context.ExecuteCommand("DELETE FROM Entity");

Ou

context.ExecuteCommand("TRUNCATE TABLE Entity");

A maneira como você está excluindo está demorando porque o Linq to SQL gera uma instrução DELETE para cada entidade . Existem outras abordagens seguras para fazer exclusões / atualizações em lote. Verifique os seguintes artigos:

Christian C. Salvadó
fonte
certifique-se de corrigir a palavra "EXCLUIR"
David,
9
Eu marquei isto com +1. Aqui está uma referência explicando a diferença entre Truncar (o que eu acho que você deseja fazer) e Excluir: mssqltips.com/tip.asp?tip=1080
David
1
+1 no comentário de David: truncar pode ser muito mais rápido do que excluir
Fredrik Mörk,
1
@David: Esse problema é específico do Entity Framework ( Linq-to-Entities ), eu usei TRUNCATEantes sem problemas no Linq-to-SQL
Christian C. Salvadó
1
TRUNCATE irá limpar qualquer indexação automática que tenha sido estabelecida (normalmente uma coluna Id), então tome cuidado se você não quiser que isso seja redefinido. DELETE FROM não.
JCisar
20

Infelizmente, o LINQ-to-SQL não executa consultas baseadas em conjunto muito bem.

Você presumiria que

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

irá traduzir para algo como

DELETE FROM [Entities]

mas infelizmente é mais 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) ...

Você descobrirá o mesmo quando tentar fazer uma atualização em massa no LINQ-to-SQL. Mais do que algumas centenas de linhas por vez e simplesmente vai ficar muito lento.

Se você precisa fazer operações em lote e está usando LINQ-to-SQL, precisa escrever procedimentos armazenados.

Kirk Broadhurst
fonte
12

Eu gosto de usar um Método de Extensão, conforme o seguinte:

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
fonte
0

você também pode usar isto:

Public void BorraFilasTabla()
{
 using(basededatos db = new basededatos())
 {
  var ListaParaBorrar = db.Tabla.Tolist();
  db.Tabla.RemoveRange(ListaParaBorrar); 
 }
}
Gerardo Guajardo
fonte
A pergunta é: "Existe uma maneira mais rápida?". Como isso seria mais rápido? Além disso, isso não é LINQ to SQL.
Gert Arnold
-1

O código c # abaixo é usado para inserir / atualizar / excluir / excluir tudo em uma tabela de banco de dados 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();                        
        }
    }
}

fonte
1
adicione alguma explicação
Yahya Hussein