2012-11-14 8 views
26

Ho letto molti post relativi a questo problema, ma non sono riuscito a trovare una risposta. Sto provando a caricare una grande quantità di dati da Excel in SQL Server. Migliaia di record. E ottengo questa eccezione:Eccezione EF: i dati stringa o binari verrebbero troncati. La dichiarazione è stata chiusa.?

Stringa o dati binari sarebbero troncati. La dichiarazione è stata terminata.

Ovviamente alcuni valori superano le dimensioni del campo nel database. L'errore proviene da SQL Server AFIK.


La mia domanda - Come avrei potuto sapere che cosa registrare e quale valore di campo causato questo?

Non ci sono dettagli specifici nell'eccezione EF, tranne quella menzionata.

Qualsiasi aiuto è apprezzato.

Alcuni hanno chiesto per il frammento di codice, ma in realtà è molto semplice, il problema non è con il codice:

// employees is a List<Employee> collection loaded from Excel 
using (var context = new Entities()) 
{ 
    employees.ForEach(e => context.Employee.AddObject(e)); 
    context.SaveChanges(); 
} 

anche l'approccio suggerito di utilizzare DbEntityValidationException (che è disponibile solo in Entity Framework 5.0) non funziona, il blocco cattura non ha rilevato l'eccezione.

try 
{ 
    ImportData(); 
} 
catch (DbEntityValidationException ex) 
{ 
    foreach (var item in ex.EntityValidationErrors) 
    { 
     //... 
    } 
} 

L'unica soluzione che ho trovato finora è quello di utilizzare SQL Server Profiler, e definire i seguenti eventi da monitorare:

enter image description here

enter image description here

Ora riesco a vedere l'email è troppo lunga

+0

Eseguire il debug di record finché non si trova l'autore del reato e controllare ogni campo del record rispetto alle colonne db? – yoozer8

+0

Si prega di fornire ulteriori informazioni per esempio esempio di codice, Struttura dati e DataType dei campi che si sta tentando di importare. Questo renderà più facile a mio parere prestare una sorta di direzione – MethodMan

+2

Non è possibile in alcun modo eseguire il debug di record usando EF. Viene eseguito come un'unica transazione. – monstro

risposta

5
catch (DbEntityValidationException ex) 
{ 
    foreach (var item in ex.EntityValidationErrors) 
    { 
     //... inspect here 
    } 
} 

È possibile trovare le informazioni necessarie all'interno del ciclo foreach.

Spero che questo aiuti.

+0

Grazie, ho appena provato, ma con cattura non intercetta l'eccezione. – monstro

+1

Se questo errore non viene generato in DbEntityValidationException, significa che il modello non è sincronizzato con il database. Prova a ricreare il modello dal database perché è ancora il modo più semplice per determinare il campo problematico. –

+0

Lo stesso qui. Su miei SaveChanges in EF6.01 dove un campo è troppo lungo, ottengo un SqlException come eccezione interna all'interno di un UpdateException all'interno di DbUpdateException. Il mio modello è sincronizzato. – Dave

3

Non è possibile a quel livello. SQL Server rifiuta l'intera query.

vorrei aggiungere alcuni controlli necessari ai dati contro i tuoi vincoli del database per la dimensione della stringa, formati di data, ecc

In alternativa si potrebbe TRIM ogni campo di stringa nei dati grezzi alla dimensione campo corrispondente prima di tentare di inserire.

+0

Non riesco a eseguire alcuna pulizia o correzione dei dati. Tutto ciò di cui ho bisogno è di trovare quale valore sta causando il problema ed espandere il campo corrispondente nel database. – monstro

+0

È possibile ottenere la lunghezza di ciascuna stringa nei dati per vedere quali sono più lunghi del campo di destinazione? –

0

Non si è sicuri del troncamento specifico, ma ecco un suggerimento per quando si ottiene un'eccezione che ti dice di esaminare EntityValidationErrors.Di solito quando esegui il debug non ti consente di vedere quella proprietà (a meno che tu non abbia già avuto una cattura esplicita). Tuttavia, è possibile aprire l'orologio rapido e digitare $exception. Ora dovresti riuscire a trivellare e trovare quella proprietà. È anche possibile digitare il seguente:

(System.Data.Entity.Validation.DbEntityValidationException)$exception 
0
private static string FindLongStrings(object testObject) 
    { 
     foreach (PropertyInfo propInfo in testObject.GetType().GetProperties()) 
     { 
      foreach (ColumnAttribute attribute in propInfo.GetCustomAttributes(typeof(ColumnAttribute), true)) 
      { 
       if (attribute.DbType.ToLower().Contains("varchar")) 
       { 
        string dbType = attribute.DbType.ToLower(); 
        int numberStartIndex = dbType.IndexOf("varchar(") + 8; 
        int numberEndIndex = dbType.IndexOf(")", numberStartIndex); 
        string lengthString = dbType.Substring(numberStartIndex, (numberEndIndex - numberStartIndex)); 
        int maxLength = 0; 
        int.TryParse(lengthString, out maxLength); 

        string currentValue = (string)propInfo.GetValue(testObject, null); 

        if (!string.IsNullOrEmpty(currentValue) && currentValue.Length > maxLength && lengthString!="max") 
         return testObject.GetType().Name + "." + propInfo.Name + " " + currentValue + " Max: " + maxLength; 

       } 
      } 
     } 
     return ""; 
    } 


foreach (object insert in dtx.GetChangeSet().Inserts) 
      { 
       string result = FindLongStrings(insert); 
       if (string.IsNullOrEmpty(result) == false) 
       { 
        responseBuilder.Append(result); 
       } 
      } 

Se responseBuilder non è vuota, allora contiene il nome del campo, lunghezza consentita e il messaggio di errore.

Problemi correlati