2012-12-31 5 views
6

Sto cercando di fare un aggiornamento per una tabella utilizzando 5.x utilizzando EF allegare. questa tabella ha altri campi che sono obbligatori ma è una riga esistente. quindi sto cercando di aggiornare senza alcun recupero. userid è la chiave primaria per la tabella. sto cercando di aggiornare lo stato. ma lancia un EntityValidationErrors che dice che è richiesta la password, che è un altro campo obbligatorio ma non la chiave primaria. poiché questo è un aggiornamento alla riga esistente, perché è necessario fornire i campi richiesti per l'aggiornamento?Attaccare per l'aggiornamento Entity Framework

+0

sulla prima riga si sta creando un nuovo 'webUser' e non andare a prendere uno dal database. prova a impostare un punto di interruzione e vedi se la password di 'webUser's' non è' null'. – Yoav

+0

non ho voluto recuperare i dati. dato che stavo per fare un aggiornamento e ho già una chiave primaria –

risposta

1

Nel quadro entità, non puoi aggiornare un campo senza impostare valori appropriati per gli altri campi. quindi è meglio usare una stored procedure per il tuo lavoro. e l'altro modo è di recuperare il record e quindi aggiornare il campo.

+1

È possibile impostare dbxupdate.Configuration.ValidateOnSaveEnabled = false per disabilitare la convalida in fase di salvataggio come in http://stackoverflow.com/a/33121240/2353894 – nhkhanh

+0

La soluzione sporca e ottimale. Potresti dover affrontare un sacco di problemi quando provi ad aggiornare una tabella esistente usando EF. – Jacob

2

L'entità viene convalidata al salvataggio, indipendentemente dal fatto che sia stata allegata o caricata dal database. Se si utilizzano gli attributi di convalida o un metodo di convalida, l'entità deve passare la convalida per essere salvata.

Se si dispone di un attributo [Required] sul campo della password Penso che tu sia abbastanza bloccato. Probabilmente devi caricare l'entità e quindi aggiornare le informazioni anziché limitarti a collegarle.

+0

no non ho questo attributo Dati. è richiesto a livello Db ma non su EF, suppongo che ADO.net abbia estratto questo attributo da db.non vedo quell'attributo sul codice generato –

+0

sembra che devo creare un SP per fare questo. –

+0

Se si desidera aggiornare solo una parte del record senza prima caricare l'intera entità, un SP è probabilmente un buon modo sì. –

0

provare questo: sostituire la prima linea con (posto questo all'interno della dichiarazione using) Codice
var wu = dbxupdate.webUsers.single(i=>i.id== webUserId);
wu.OnlineStatus = whatever;

continua ... al fine di aggiornare un'entità è necessario ottenere un'istanza di esso. altrimenti ne stai creando uno nuovo in cui le proprietà che non sono dichiarate hanno un valore null.

14

.Attach() è davvero utile solo per aggiornare le entità in uno scenario indipendente come questo:

User entity = null; 

using (var db = new DbContext()) 
{ 
    entity = (from p in db.Users 
       where p.id == 1 
       select p).FirstOrDefault(); 

    System.Diagnostics.Trace.WriteLine(entity.Name); //Outputs "Jane Doe" 
} 

entity.Name = "John Doe" //Modified while no longer connected to database 

using (var db = new DbContext()) 
{ 
    db.Users.Attach(entity); 
    db.Entry(entity).Property(a => a.Name).IsModified = true; 
    db.SaveChanges(); 

    System.Diagnostics.Trace.WriteLine(entity.Name); //Now outputs "John Doe" 
} 

nello scenario l'entità che si sta creando non viene recuperato è la chiave e il database sta trattando come un'entità completamente nuova. Presumo che la tua password sia un campo non annullabile e quindi EF genera un errore quando provi a salvare le tue modifiche. Se non avevi tali errori, EF cancellerebbe automaticamente tutti i campi che non hai modificato e quindi salverai l'entità (che non è il risultato che stai cercando).

Al fine di apportare le modifiche che stai cercando, allora probabilmente dovrete fare qualcosa di simile al seguente:

using (var db = new DbContext()) 
{ 
    db.Users.Single(a => a.id == 1).OnlineStatus = (sbyte)status; 
    db.SaveChanges 
} 

e quindi aggiungere qualsiasi altro codice di gestione degli errori/convalida che si desidera. In alternativa è possibile memorizzare l'entità in variabile per apportare modifiche a più di un campo alla volta. EF dovrebbe determinare automaticamente quali valori sono stati modificati e generare solo l'SQL richiesto per apportare tali modifiche. Il che significa che se si ha qualcosa di simile:

foreach (var item in entityList) 
{ 
    var entity = db.Users.Single(a => a.id == item.id); 

    entity.Name = item.Name; 
    entity.Address = item.Address; 
} 

qualcuno mi corregga se sbaglio, ma EF dovrebbe aggiornare solo le entità/campi che sono effettivamente interessati da questo codice. Se il nome o l'indirizzo rimane invariato, EF salterà quel campo per quell'entità quando salva le modifiche al database.