Entity Framework: "L'istruzione di aggiornamento, inserimento o eliminazione dello store ha interessato un numero imprevisto di righe (0)." [chiuso]


324

Sto usando Entity Framework per popolare un controllo di griglia. A volte quando faccio aggiornamenti ottengo il seguente errore:

L'istruzione di aggiornamento, inserimento o eliminazione dello store ha interessato un numero imprevisto di righe (0). Le entità potrebbero essere state modificate o eliminate da quando le entità sono state caricate. Aggiorna voci ObjectStateManager.

Non riesco a capire come riprodurlo. Ma potrebbe avere qualcosa a che fare con quanto vicino faccio gli aggiornamenti. Qualcuno ha visto questo o qualcuno sa a cosa si riferisce il messaggio di errore?

Modifica: Sfortunatamente non sono più libero di riprodurre il problema che avevo qui, perché mi sono allontanato da questo progetto e non ricordo se alla fine ho trovato una soluzione, se un altro sviluppatore l'ha risolto o se ci ho lavorato. Pertanto non posso accettare alcuna risposta.


Ho riscontrato questo errore con l'introduzione di una politica di sicurezza a livello di riga di SQL Server che consentiva gli aggiornamenti di una riga in uno stato che non poteva essere riletto (un predicato FILTER esclusivo con un predicato BLOCK permissivo) . EntityFramework richiede la lettura della riga aggiornata dopo l'aggiornamento, altrimenti presuppone che si sia trattato di un errore di concorrenza (almeno quando si utilizza la concorrenza ottimistica).
xr280xr

Il problema potrebbe essere di scoping non corretta per il vostro DbContext stackoverflow.com/questions/49154250/... (questo esempio è per ASPNET identità, ma vale per qualsiasi contesto)
Simon_Weaver

Indipendentemente dal contesto di questo errore, è una buona idea mettere un punto di interruzione ovunque sia il momento in cui viene istanziato il contesto. Ti aspettavi che venisse istanziato una volta quando hai caricato una pagina web ma ha colpito quel punto di interruzione 5 volte? Quindi probabilmente hai una condizione di gara. Guarda Request.Uriper vedere l'URL della richiesta effettiva. Nel mio caso avevo una logica di tracciamento che stava colpendo il mio sito e caricando inutilmente il contesto dal DB (e occasionalmente aggiornandolo). Quindi la pagina reale di cui stavo eseguendo il debug aveva avuto i suoi dati calpestati da una stupida logica del codice di monitoraggio.
Simon_Weaver,

aggiungi @ Html.AntiForgeryToken () in vista
Vikas Sharma

Risposte:


199

Questo è un effetto collaterale di una funzionalità chiamata concorrenza ottimistica.

Non sono sicuro al 100% su come attivarlo / disattivarlo in Entity Framework, ma fondamentalmente quello che ti dice è che tra quando hai estratto i dati dal database e quando hai salvato le modifiche qualcun altro ha cambiato i dati (il che significava quando sei andato per salvarlo 0 righe effettivamente aggiornate). In termini SQL, la loro updatequerywhere clausola contiene il valore originale di ogni campo della riga e se sono interessate 0 righe, sa che qualcosa è andato storto.

L'idea alla base è che non finirai per sovrascrivere una modifica che la tua applicazione non sapeva fosse accaduta - è fondamentalmente una piccola misura di sicurezza introdotta da .NET su tutti i tuoi aggiornamenti.

Se è coerente, ci sono delle probabilità che stia accadendo all'interno della tua logica (ad esempio: stai effettivamente aggiornando i dati tu stesso in un altro metodo tra la selezione e l'aggiornamento), ma potrebbe essere semplicemente una condizione di competizione tra due applicazioni.


34
Questo sta accadendo in un ambiente a utente singolo (sulla mia macchina di sviluppo), quindi non credo che potrebbe essere una condizione di competizione. Sono vincolante per un controllo griglia personalizzato con EntityDataSource, quindi non sono sicuro esattamente cosa sta succedendo dietro le quinte, ma non ho alcun codice aggiuntivo che sta modificando le tabelle. C'è un modo per cambiare questa impostazione di concorrenza?
strongopinions il

3
Penso che puoi farlo per colonna nel tuo modello di entità (è nella finestra delle proprietà), ma il fatto è che ti impedirà di vedere l'errore e non aggiornerà ancora nulla. Sei in grado di visualizzare i comandi SQL nel tuo database (ad es. SQL Server Profiler per MSSQL)? In questo modo potresti vedere quale aggiornamento viene generato e dovresti essere in grado di capire perché tale aggiornamento non influisce su nessuna riga.
Fyjham,

9
Se l'entità ha una proprietà timestamp, assicurati di averla memorizzata nella tua vista e assicurati che l'entità compili correttamente il timestamp.
anIBMer,

Avevo una colonna timestamp e una volta indirizzata a essa, EF6.1 ha funzionato come previsto, grazie per il suggerimento @anelBMer
JQII

3
Se si utilizzano i timestamp, l'oggetto tje che si desidera eliminare richiede il set PK e la proprietà RowVersion per aggiornarlo correttamente! Stavo impostando la proprietà rowVersion (timestamp), dopo aver collegato l'oggetto al rispettivo DbSet, ecco perché non ha funzionato. Buon lavoro!
Legends,

394

Mi sono imbattuto in questo ed è stato causato dal campo ID (chiave) dell'entità non impostato. Pertanto, quando il contesto è andato a salvare i dati, non è stato possibile trovare un ID = 0. Accertarsi di inserire un punto di interruzione nell'istruzione di aggiornamento e verificare che l'ID dell'entità sia stato impostato.

Dal commento di Paul Bellora

Ho avuto questo esatto problema, causato dalla dimenticanza di includere l'input ID nascosto nella pagina di modifica .cshtml


3
+1 Avevo lo stesso problema e questo mi ha aiutato a trovare la soluzione. Si scopre che avevo [Bind (Exclude = "OrderID")] nel mio modello di ordine che stava causando il valore zero dell'ID entità su HttpPost.
Dhaust

2
Questo è esattamente quello che mi mancava. L'ID del mio oggetto era 0.
Azhar Khorasany il

4
@ Html.HiddenFor (model => model.productID) - ha funzionato perfettamente. Mi mancava il productID nella MODIFICA PAGINA (MVC RAZOR)
Ravi Ram,

2
Ho avuto un problema simile ma con una svolta. Per me il problema era che non avevo configurato correttamente la tabella sql. Il mio campo chiave primaria non era impostato su incremento automatico. Quindi EF avrebbe inviato il record che stavo cercando di inserire senza chiave, il che va bene se ti ricordi di dire a sql che il campo è un campo Identità con incremento automatico, che ho dimenticato: <
Agile Noob

1
Stesso problema ma utilizzo di una chiave composita. Uno dei valori chiave non è stato impostato.
obaylis,

113

Wow, molte risposte, ma ho avuto questo errore quando ho fatto qualcosa di leggermente diverso che nessun altro ha menzionato.

Per EntityState.Modifiedfarla breve, se si crea un nuovo oggetto e si dice a EF che è stato modificato utilizzando il , verrà generato questo errore in quanto non esiste ancora nel database. Ecco il mio codice:

MyObject foo = new MyObject()
{
    someAttribute = someValue
};

context.Entry(foo).State = EntityState.Modified;
context.SaveChanges();

Sì, questo sembra stupido, ma è nato perché il metodo in questione era foopassato ad esso essendo stato creato in precedenza, ora è someValuepassato solo ad esso e si crea foo.

Facile correzione, basta cambiare EntityState.Modifieda EntityState.Addedo cambiamento che tutta la linea a:

context.MyObject.Add(foo);

Grazie per aver pubblicato questo Anche questo era il mio problema, avevo copiato e incollato del codice che stava impostando lo stato su EntityState.Modified.
clayRay,

23

Stavo affrontando questo stesso errore spaventoso ... :) Poi mi sono reso conto che stavo dimenticando di impostare un

@Html.HiddenFor(model => model.UserProfile.UserId)

per la chiave primaria dell'oggetto da aggiornare! Tendo a dimenticare questa cosa semplice, ma molto importante!

A proposito: HiddenForè per ASP.NET MVC.


3
Sembra un difetto di sicurezza, per archiviarlo UserIdnella forma, molto incline agli hacker ... questo dovrebbe essere popolato in seguito daHttpContext.Current.User.Identity.Name
Serj Sagan,

@SerjSagan hai ragione ... ma finché fai qualche controllo sul lato server per confermare UserId e Current UserName sei a posto.
Leniel Maccaferri,

1
Il mio punto è il motivo per cui anche memorizzarlo nel HiddenFornecessario per ottenerlo dal HttpContextcomunque ... Non metterei questa proprietà nel modulo, il che mi costringerebbe a popolarla sempre sul lato server ...
Serj Sagan

16

Controlla se hai dimenticato l'attributo "DataKeyNames" in GridView. è un must quando si modificano i dati all'interno di GridView

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx


+1. Soluzione perfetta e semplice per me. Sto associando GridView a EntityDataSource e non l'ho impostato sulla mia chiave primaria sull'oggetto.
Andez,

Sappiamo che l'interfaccia utente di Kendo non supporta la chiave composita, ma nel caso in cui aggiungessi una nuova colonna che concatenasse le mie chiavi a una, cosa sta succedendo allora?
Branislav,

15

Il problema è causato da una di queste due cose:

  1. Hai provato ad aggiornare una riga con una o più proprietà sono Concurrency Mode: Fixed.. e la concorrenza ottimistica ha impedito il salvataggio dei dati. Vale a dire. alcuni hanno modificato i dati della riga tra il momento in cui hai ricevuto i dati del server e quando hai salvato i dati del server.
  2. Hai provato ad aggiornare o eliminare una riga ma la riga non esiste. Un altro esempio di qualcuno che modifica i dati (in questo caso, rimuovendo) tra un recupero e poi salva O stai pianificando il nostro tentativo di aggiornare un campo che non è un'Identità (es. StoreGeneratedPattern = Computed) E quella riga non esiste.

1
Ciò potrebbe anche essere causato se tutte le proprietà dell'oggetto a cui erano state assegnate, fossero state assegnate con gli stessi valori di prima.
Serj Sagan,

+1 per la seconda. StoreGeneratedPattern = Nessuno, passando a StoreGeneratedPattern = Identity ha risolto il problema. Grazie
tkt986,

12

Ho avuto lo stesso errore perché parte del PK era una colonna datetime e il record che veniva inserito utilizzava DateTime.Oow come valore per quella colonna. Il framework di entità inserisce il valore con precisione in millisecondi, quindi cerca il valore che ha appena inserito anche con precisione in millisecondi. Tuttavia, SqlServer ha arrotondato il valore alla seconda precisione, e quindi il framework dell'entità non è stato in grado di trovare il valore di precisione in millisecondi.

La soluzione consisteva nel troncare i millisecondi di DateTime.Oow prima dell'inserimento.


2
Abbiamo avuto lo stesso problema, tranne che ci stavamo inserendo in una Datecolonna con un DateTimevalore
adam0101,

1
Anch'io. Avevamo un registro del data warehouse e utilizzavamo il timestamp come parte della chiave. Il timestamp nel data warehouse era un DateTime SQL, ma il timestamp in C # non corrispondeva. Ho cambiato il tipo di dati SQL in DateTime2 (7), ho aggiornato il modello EF e tutto è stato risolto.
mmcfly,

Cambiare la colonna in Datetime2 (7) ha funzionato anche per me. Grazie @mmcfly
Dzejms il

10

Avevo lo stesso problema e la risposta di @ webtrifusion mi ha aiutato a trovare la soluzione.

Il mio modello utilizzava l' Bind(Exclude)attributo sull'ID dell'entità che causava il valore dell'ID dell'entità su zero su HttpPost.

namespace OrderUp.Models
{
[Bind(Exclude = "OrderID")]
public class Order
{
    [ScaffoldColumn(false)]
    public int OrderID { get; set; }

    [ScaffoldColumn(false)]
    public System.DateTime OrderDate { get; set; }

    [Required(ErrorMessage = "Name is required")]
    public string Username { get; set; }
    }
}   

Problema simile, per motivi di sicurezza, ho Bind (include = alcuni campi). L'ID non era nell'elenco. Inoltre l'ho aggiunto come input nascosto. Deve aver cancellato qualcosa generato da MVC o l'ID non c'era affatto. Grazie per l'aiuto.
MusicAndCode

10

Ho avuto lo stesso problema, ho capito che era causato dalla RowVersion che era nulla. Verifica che il tuo ID e RowVersion non siano nulli .

per ulteriori informazioni consultare questo tutorial

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application


la versione della riga era nulla nel mio caso
Prakash,

Nel mio caso avevo accidentalmente rimosso il campo Id nel mio [Bind (Include = properties)]. Aggiungilo di nuovo e ha funzionato bene.
Caverman,

8

Ho iniziato a ricevere questo errore dopo essere passato dal primo modello al primo codice. Ho più thread che aggiornano un database in cui alcuni potrebbero aggiornare la stessa riga. Non so perché non ho avuto problemi con l'utilizzo del modello, suppongo che utilizzi un valore predefinito di concorrenza diverso.

Per gestirlo in un posto conoscendo le condizioni in cui potrebbe verificarsi, ho aggiunto il seguente sovraccarico alla mia classe DbContext:

using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;

public class MyDbContext: DbContext {
...
        public int SaveChanges(bool refreshOnConcurrencyException, RefreshMode refreshMode = RefreshMode.ClientWins) {
            try {
                return SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex) {
                foreach (DbEntityEntry entry in ex.Entries) {
                    if (refreshMode == RefreshMode.ClientWins)
                        entry.OriginalValues.SetValues(entry.GetDatabaseValues());
                    else
                        entry.Reload();
                }
                return SaveChanges();
            }
        }
}

Quindi chiamato SaveChanges(true)ovunque applicabile.


1
OK, tutti gli altri si lamentano del problema, mostrando come possono innescarlo ecc., Ma questa risposta ha una risposta interessante. Uso un modello di aggiornamento continuo (nessun pulsante di salvataggio qui baby) e lo stavo ottenendo sugli aggiornamenti della griglia quando il thread EF era in ritardo e l'ho risolto. Brillante lavoro, buon nome ... mi hai fatto sembrare un eroe - in piedi sulla spalla di giganti !!
Tony Trembath-Drake,

Aiutato anche me, guarda questo per ulteriori opzioni- stackoverflow.com/a/13891724/4836581
Zvi Redler

7

È necessario includere esplicitamente un BoundField della chiave primaria. Se non vuoi che l'utente veda la chiave primaria, devi nasconderla tramite CSS:

    <asp:BoundField DataField="Id_primary_key" ItemStyle-CssClass="hidden" 
HeaderStyle-CssClass="hidden" />

Dove "nascosto" è una classe in CSS che ha il display impostato su "nessuno".


1
ah, mi hai fatto capire che ho cancellato il mio campo ID nascosto in ASP.NET MVC. Grazie @Paulo! :)
Tomasz Iniewicz,

7

Durante la modifica includere l'id o la chiave primaria dell'entità come campo nascosto nella vista

vale a dire

      @Html.HiddenFor(m => m.Id)

questo risolve il problema.

Inoltre, se il tuo modello include articoli non utilizzati, includi anche quello e pubblicalo sul controller


7

Ho anche riscontrato questo errore. Il problema si è scoperto è stato causato da un trigger sul tavolo che stavo cercando di salvare. Il trigger ha usato "INSTEAD OF INSERT", il che significa che 0 righe sono mai state inserite in quella tabella, quindi l'errore. Fortunatamente in questo caso la funzionalità di trigger era errata, ma suppongo che potrebbe essere un'operazione valida che dovrebbe in qualche modo essere gestita nel codice. Spero che questo aiuti qualcuno un giorno.


2
È possibile indurre l'entità a credere che le righe siano state aggiunte restituendo un'istruzione SELECT (con la colonna chiave primaria) dal trigger.
jahu,

1
Per espandere il commento di @jahu, ho dovuto ottenere un ID effettivo dell'elemento appena inserito per essere restituito dal mio trigger e il nome della colonna deve corrispondere alla colonna dell'identità della tabella dei trigger (nel mio caso, in realtà una vista, quindi non ha non ha una sua identità, ma avevo ingannato l'edmx nel credere che lo fosse). Il mio trigger stava facendo un inserimento in una tabella separata, quindi ho appena aggiunto quest'ultima riga al mio trigger:SELECT SCOPE_IDENTITY() as MyViewId
DannyMeister,


Nel mio caso stavo eseguendo un'operazione di eliminazione su entità in una raccolta figlio, ma c'era un trigger su eliminazione per una delle entità figlio che causava l'eliminazione di un'altra delle entità figlio. Ciò ha causato l'errore poiché le righe N - 1 sono state interessate a causa del trigger che ha eliminato una delle entità figlio stesse prima che il framework delle entità tentasse di eliminarlo.
scheletro

6

Mi sono imbattuto in questo problema su una tabella in cui mancava una chiave primaria e aveva una colonna DATETIME (2, 3) (quindi la "chiave primaria" dell'entità era una combinazione di tutte le colonne) ... Durante l'esecuzione dell'inserimento il timestamp aveva un tempo più preciso (20-03-2018 08: 29: 51.8319154) che è stato troncato in (20-03-2018 08: 29: 51.832) in modo che la ricerca sui campi chiave non riesca.


5

Ho anche avuto questo errore. Esistono alcune situazioni in cui l'Entità potrebbe non essere a conoscenza del contesto di database effettivo in uso o il Modello potrebbe essere diverso. Per questo, impostare: EntityState.Modified; a EntityState.Added;

Per fare questo:

if (ModelState.IsValid)
{
context.Entry(yourModelReference).State = EntityState.Added;
context.SaveChanges();
}

Questo assicurerà che l'Entità sappia che stai usando o aggiungendo lo Stato con cui stai lavorando. A questo punto è necessario impostare tutti i valori di modello corretti. Fare attenzione a non perdere eventuali modifiche che potrebbero essere state apportate in background.

Spero che questo ti aiuti.


1
sei un gurú! funziona per me!
Hernaldo Gonzalez,

5
  @Html.HiddenFor(model => model.RowVersion)

La mia rowversion era nulla, quindi ho dovuto aggiungere questo alla vista che ha risolto il mio problema


Non stavo passando RowVersion dalla vista all'azione di modifica, inoltre ho dimenticato di eseguire il binding del modello per RowVersion. Nel momento in cui si sta salvando l'oggetto in db, è necessario il valore precedente di RowVersion da inviare al db insieme all'oggetto per il controllo della concorrenza. Fai errori sciocchi quando hai bisogno di cose più velocemente!
Dhanuka777,

5

La linea [DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]ha funzionato nel mio caso:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;


[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int? SomeNumber { get; set; }

4

Assicurati solo che sia la tabella che il modulo abbiano la chiave primaria ed edmx aggiornati.

ho riscontrato che gli errori durante l'aggiornamento erano generalmente dovuti a: - Nessuna chiave primaria nella tabella - Nessuna chiave primaria nella vista Modifica / modulo (ad es. @Html.HiddenFor(m=>m.Id)


4

Ho avuto lo stesso problema. Nel mio caso stavo cercando di aggiornare la chiave primaria, che non è consentita.


4

Ho avuto questo errore sporadicamente quando ho usato un async metodo. Non è successo da quando sono passato a un metodo sincrono.

Errori sporadici:

[Authorize(Roles = "Admin")]
[HttpDelete]
[Route("file/{id}/{customerId}/")]
public async Task<IHttpActionResult> Delete(int id, int customerId)
{
    var file = new Models.File() { Id = id, CustomerId = customerId };
    db.Files.Attach(file);
    db.Files.Remove(file);

    await db.SaveChangesAsync();

    return Ok();
}

Funziona sempre:

[Authorize(Roles = "Admin")]
[HttpDelete]
[Route("file/{id}/{customerId}/")]
public IHttpActionResult Delete(int id, int customerId)
{
    var file = new Models.File() { Id = id, CustomerId = customerId };
    db.Files.Attach(file);
    db.Files.Remove(file);

    db.SaveChanges();

    return Ok();
}

Sebbene questo abbia risolto il mio problema, è servito a indicare il problema di base menzionato in precedenza in questo post sulle versioni PK e Row. Avevo trascurato di aggiungere una mappa dello schema per una nuova tabella che era ulteriormente complicata dal fatto che il PK non seguiva la regola della convenzione di denominazione. ID <nome tabella>.
midohioboarder,

3

Ho avuto quell'errore quando stavo cancellando alcune righe nel DB (nel ciclo) e aggiungendo quelle nuove nella stessa tabella.

La soluzione per me è stata quella di creare dinamicamente un nuovo contesto in ogni iterazione di loop


Ho dovuto fare la stessa cosa, ancora non sono sicuro del motivo per cui il problema si è verificato in primo luogo, ma funziona.
Jed Grant,

3
    public void Save(object entity)
    {
        using (var transaction = Connection.BeginTransaction())
        {
        try
                {
                    SaveChanges();
                    transaction.Commit();
                }
                catch (OptimisticConcurrencyException)
                {
                    if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Deleted || ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Modified)
                        this.Refresh(RefreshMode.StoreWins, entity);
                    else if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Added)
                        Detach(entity);
                    AcceptAllChanges(); 
                    transaction.Commit();
                }
        }
    }

Potete chiarire a cosa si riferisce "questo" qui e cos'è ObjectStateManager? Sto provando questo nella nostra classe di repository di base ma ricevo errori
Naomi il

3

Ciò accadrà anche se stai cercando di inserire una situazione di vincolo unica, ovvero se puoi avere un solo tipo di indirizzo per datore di lavoro e provi a inserire un secondo dello stesso tipo con lo stesso datore di lavoro, otterrai lo stesso problema .

O

Ciò può accadere anche se tutte le proprietà dell'oggetto a cui sono state assegnate, sono state assegnate con gli stessi valori di prima.

        using(var db = new MyContext())
        {
            var address = db.Addresses.FirstOrDefault(x => x.Id == Id);

            address.StreetAddress = StreetAddress; // if you are assigning   
            address.City = City;                   // all of the same values
            address.State = State;                 // as they are
            address.ZipCode = ZipCode;             // in the database    

            db.SaveChanges();           // Then this will throw that exception
        }

2

Se stai provando a creare una mappatura nel tuo file edmx su una "funzione Importazioni", questo errore può causare questo errore. Deseleziona semplicemente i campi per l'inserimento, l'aggiornamento e l'eliminazione che si trova in Dettagli di mappatura per una determinata entità nel tuo edmx e dovrebbe funzionare. Spero di averlo chiarito.


2

Ho ottenuto questa eccezione quando ho collegato un oggetto che non esisteva nel database. Avevo supposto che l'oggetto fosse caricato da un contesto separato, ma se era la prima volta che l'utente visitava il sito, l'oggetto veniva creato da zero. Abbiamo chiavi primarie a incremento automatico, quindi potrei sostituirle

context.Users.Attach(orderer);

con

if (orderer.Id > 0) {
    context.Users.Attach(orderer);
}

2

Bene ho questo stesso problema. Ma questo era dovuto al mio errore. In realtà stavo salvando un oggetto invece di aggiungerlo. Quindi questo era il conflitto.


2

Un modo per eseguire il debug di questo problema in un ambiente SQL Server è utilizzare il Profiler SQL incluso con la copia di SQL Server o, se si utilizza la versione Express, ottenere una copia di Express Profiler gratuitamente da CodePlex seguendo il seguente link:

Express Profiler

Utilizzando Sql Profiler è possibile accedere a tutto ciò che viene inviato da EF al DB. Nel mio caso ciò equivaleva a:

exec sp_executesql N'UPDATE [dbo].[Category]
SET [ParentID] = @0, [1048] = NULL, [1033] = @1, [MemberID] = @2, [AddedOn] = @3
WHERE ([CategoryID] = @4)
',N'@0 uniqueidentifier,@1 nvarchar(50),@2 uniqueidentifier,@3 datetime2(7),@4 uniqueidentifier',
@0='E060F2CA-433A-46A7-86BD-80CD165F5023',@1=N'I-Like-Noodles-Do-You',@2='EEDF2C83-2123-4B1C-BF8D-BE2D2FA26D09',
@3='2014-01-29 15:30:27.0435565',@4='3410FD1E-1C76-4D71-B08E-73849838F778'
go

Copio questo incollato in una finestra di query in SQL Server ed eseguito. Abbastanza sicuro, anche se è stato eseguito, 0 record sono stati interessati da questa query, quindi l'errore è stato restituito da EF.

Nel mio caso il problema è stato causato dal CategoryID.

Non è stato identificato un ID categoria identificato dall'ID EF inviato al database, pertanto sono interessati 0 record.

Non è stata colpa di EF, ma piuttosto di una buggy a coalescenza nulla "??" istruzione in un controller di visualizzazione che stava inviando sciocchezze al livello dati.


2

Nessuna delle risposte di cui sopra ha abbastanza coperto la mia situazione e la soluzione ad essa.

Codice in cui è stato generato l'errore nel controller MVC5:

        if (ModelState.IsValid)
        {
            db.Entry(object).State = EntityState.Modified; 
            db.SaveChanges(); // line that threw exception
            return RedirectToAction("Index");
        }

Ho ricevuto questa eccezione quando stavo salvando un oggetto da una vista Modifica. Il motivo per cui è stato lanciato è perché quando sono tornato per salvarlo, avevo modificato le proprietà che costituivano la chiave primaria sull'oggetto. Pertanto, impostare il suo stato su Modified non aveva alcun senso per EF: era una nuova voce, non una precedentemente salvata.

Puoi risolverlo sia A) modificando la chiamata di salvataggio in Aggiungi l'oggetto, sia B) semplicemente non cambiare la chiave primaria in modifica. Ho fatto B).


2

Quando la risposta accettata diceva " non finirà per sovrascrivere una modifica che la tua applicazione non sapeva fosse accaduta ", ero scettico perché il mio oggetto era stato appena creato. Ma poi si scopre, c'era unINSTEAD OF UPDATE, INSERT- TRIGGER allegato alla tabella che stava aggiornando una colonna calcolata della stessa tabella.

Una volta che lo cambio AFTER INSERT, UPDATE, funzionava bene.


2

Questo mi è successo a causa di una discrepanza tra datetime e datetime2. Stranamente, ha funzionato bene prima che un tester scoprisse il problema. Il mio codice Il primo modello includeva un DateTime come parte della chiave primaria:

[Key, Column(Order = 2)]  
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;

La colonna generata è una colonna datetime. Quando si chiama SaveChanges, EF ha generato il seguente SQL:

-- Region Parameters
DECLARE @0 Int = 2
DECLARE @1 Int = 25
DECLARE @2 Int = 141051
DECLARE @3 DateTime2 = '2017-07-27 15:16:09.2630000' --(will not equal a datetime value)
-- EndRegion
UPDATE [dbo].[OrganizationSurvey]
SET [OrganizationSurveyStatusId] = @0
WHERE ((([SurveyID] = @1) AND ([OrganizationID] = @2)) AND ([PurchasedDate] = @3))

Poiché stava cercando di abbinare una colonna datetime a un valore datetime2, non ha restituito risultati. L'unica soluzione che mi è venuta in mente è stata quella di cambiare la colonna in un datetime2:

[Key, Column(Order = 2, TypeName = "DateTime2")]  
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;

1
La stranezza di esso vs lavorare non funziona ha a che fare con il sottostante formato / base datetimevs. datetime2. In sostanza, alcuni valori in millisecondi valuteranno una corrispondenza, altri no. La stessa cosa è successa a me e sono passato anche a DateTime2.
xr280xr

+1 Vorrei poter fare +100 su questo per te. Dopo aver sfogliato in molti posti ho finalmente trovato questo e ho capito che, in effetti, avevo un Datetime come parte della mia chiave primaria. Sì, questo in effetti l'ha risolto. Ho aggiornato la colonna su Datetime2 e ha funzionato. Ora, la mia carne è con Entity Framework per escogitare una domanda così schifosa per questo che mi costringe a farlo.
Catchops
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.