227 messaggi dal 07 ottobre 2004
Cercando nella documentazione Microsoft ho trovato quest'istruzione

hTd.RemoveRange(hTd.Where(t => t.TRA_INPDAT < date));

A quanto pare serve per la cancellazione di range di dati.. La sto provando ma in questo caso ottendo un timeout da parte del server.

I record che dovrebbero essere cancellati sarebbero 19000.

Questo codice gira all'interno di un servizio di windows che gira ogno 30 secondi puo influire?

ciao
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,

imbesi ha scritto:

I record che dovrebbero essere cancellati sarebbero 19000

Sono tanti, per cui le soluzioni che abbiamo valutato finora non sono adeguate perché Entity Framework va a recuperare dal db tutte le entità e poi compone 19.000 comandi DELETE che eliminano le righe una per una, in base alla loro chiave primaria. Questo è estremamente inefficiente ed è un'operazione che *potrebbe* non riuscire a completarsi in 30 secondi.

Invece a noi serve un approccio più semplice, magari una sola query come quella che scriveresti a mano, cioè:
DELETE FROM tabella WHERE TRA_INPDAT < @data;

...che è in grado di eliminare molti record in un colpo solo.

Per realizzarla, hai varie opportunità:
  • Invii la query SQL così come nell'esempio, usando il metodo Database.ExecuteSqlCommand, ma questo significherebbe rinunciare alle lambda expressions.
  • Oppure, preferibile, ti procuri da Nuget la libreria EntityFramework.Extended che trovi documentata su GitHub. Essa ti mette a disposizione un extension method Delete che causerà l'invio di un solo comando DELETE come quello che avresti scritto tu a mano. Qui il Delete supporta una lambda, quindi questa soluzione è più rispettosa di ciò che intendevi realizzare. Dalla documentazione infatti si legge:

    Batch Update and Delete
    A current limitations of the Entity Framework is that in order to update or delete an entity you have to first retrieve it into memory. [...] Batch update and delete eliminates the need to retrieve and load an entity before modifying it.


ciao,
Moreno
Modificato da BrightSoul il 30 agosto 2015 12.55 -

Enjoy learning and just keep making
227 messaggi dal 07 ottobre 2004
Con questo codice funziona

var soglia = DateTime.Now.AddDays(-30);
var sqlDelete = "DELETE TABELLA WHERE TRA_INPDAT < @periodo";
hTd.ExecuteProcedure(sqlDelete, new SqlParameter("@periodo", soglia));


Il mio problema è che la mia applicazione lavora con volume di dati molto grossa, quindi 19000 record sono solo un caso, molto spesso il volume è maggiore.

Attualmente sto testando/creando il repository con unit of work e mi sono imbattuto in questo problema del volume di dati, non vorrei che EF mi facia qualche altro brutto scherzo.

Utilizzando la seconda soluzione che proponi credi che possano esserci altri problemi? Dovrei valutare altri aspetti considerando che lavoro con grossi volumi di dati? (in alcuni casi devo anche aggiornare piu di 50.000 record)

Ciao e grazie per l'aiuto
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao,
la libreria EntityFramework.Extended è idonea per aggiornare grosse moli di dati. La lentezza, a quel punto, dipenderà unicamente da questioni legate alla complessità della query o al database, come dagli indici che hai posto sulle colonne, da quanto sono frammentati i dati e così via.

Ma fai dei test tu stesso, tanto l'unico modo per convincersi della bontà di un prodotto è quello di provarlo nel proprio scenario (magari fai esperimenti in locale o comunque su una copia del database e non su quello di produzione).

imbesi ha scritto:

non vorrei che EF mi facia qualche altro brutto scherzo.

Quello che EntityFramework.Extended non copre sono gli inserimenti massivi. Per questo c'è un'altra libreria (che però non ho mai usato, quindi dovrai fare dei test anche con questa, nel caso tu abbia effettivamente bisogno di fare inserimenti massivi).
https://efbulkinsert.codeplex.com/

Promette dei miglioramenti prestazionali sul metodo AddRange dei DbSet.

Queste librerie completano EF perché il suo compito non è tanto quello di spostare in giro grosse quantità di dati, ma di offrirti un'interfaccia di programmazione ad oggetti che astragga dal modello relazionale e che renda semplice leggere e scrivere grafi complessi di oggetti. In questo è eccezionale. Per le operazioni bulk ci sono quelle librerie che ne estendono le funzionalità.

ciao,
Moreno

Enjoy learning and just keep making
227 messaggi dal 07 ottobre 2004
Ciao

per il momento funziona!

Terro a mente i suggerimenti che mi hai dato.

Grazie ancora per il supporto

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.