2014-09-09 11 views
5

Ich habe ein Zahlungsmodell mit einem booleschen Wert 'Status', der standardmäßig auf 'false' gesetzt ist. Sobald die Zahlung erfolgt ist, muss der Status dieser bestimmten Zahlung auf "wahr" gesetzt werden.Aktualisieren des Datenbankeintrags MVC Entity Framework

Hier ist der Code, den ich versucht habe, den spezifischen Datenbankeintrag zu ändern, aber er ändert ihn einfach nicht. Was mache ich falsch?

Payment payment = new Payment(); 
payment = db.Payments.Find(orderId); 
db.Entry(payment).State = EntityState.Modified; 
payment.Status = true; 
db.SaveChanges(); 

Vielen Dank!

Dies ist, was Arbeits endete:

using (var con = new ApplicationDbContext()) 
{ 
    payment = con.Payments.First(x => x.Id == orderId); 
    payment.Status = true; 

    con.Payments.Attach(payment); 
    var entry = con.Entry(payment); 
    entry.Property(e => e.Status).IsModified = true; 
    con.SaveChanges(); 
} 
+0

Gibt db.Payments.Find (orderId) eine Zahlung zurück? –

+0

Ja, die orderId gibt an, welche Zahlung geändert werden soll (die orderId ist identisch mit der Zahlungs-ID, die bei der Zahlungserfassung erstellt wurde). – Pierre

+0

Welche Version des Entity-Frameworks verwenden Sie? –

Antwort

6
Payment payment = new Payment(); 
payment = db.Payments.Find(orderId); 
payment.Status = true; 
db.Entry(payment).State = EntityState.Modified; 
db.SaveChanges(); 
+0

bitte erklären Sie – webeno

+0

Haben Sie über diesen Beitrag vergessen, aber das ist, was ich ende mit: EDIT, wird Hauptpost mit meinem Code zu aktualisieren. – Pierre

1

Try this one:

Payment payment; 
    using (var context = new DBContext()) //replace the name of your context 
    { 
     payment = context.Payments.Find(orderId); 
    } 

    if(payment != null) 
    { 
     payment.Status = true; 
    } 

    using (var context = new DBContext()) //replace the name of your context 
    { 
     context.Payments.Attach(payment); 
     context.Entry(payment).State = System.Data.EntityState.Modified;  
     context.SaveChanges(); 
    } 
+3

Warum erstellen (und entsorgen) Sie zwei separate 'DbContexts' für dieses einfache Update? – MEMark

+0

Das gesamte Update kann definitiv unter einem einzigen Kontext durchgeführt werden. Ich habe es auf diese Weise geschrieben, weil ich nicht weiß, ob er mit angehängten Entitäten oder mit Abgetrennten arbeitet. Angehängte Entitäten erfordern die Verwendung des gleichen Kontexts für die Auswahl eines Updates. –

+0

Funktioniert immer noch nicht. Vielleicht liegt das Problem bei orderId. Ich überprüfe, ob die richtige Bestell-ID von der Zahlungs-Website veröffentlicht wurde. Aber der einzige Unterschied zwischen unserem Code ist die Codezeile mit "Attach". Ich habe diesen Begriff nie benutzt, werde auch darüber nachlesen. Danke für die Antwort, wird es als beantwortet markiert, sobald ich dieses Problem behoben habe :) – Pierre

1

Wie here erwähnt:

Die Find-Methode auf DbSet verwendet den Primärschlüsselwert versuchen, eine Entität zu finden, die vom Kontext verfolgt wird. Wenn die Entität nicht im Kontext gefunden wird, wird eine Abfrage an die Datenbank gesendet, um die Entität dort zu finden. Null wird zurückgegeben, wenn die Entität nicht im Kontext oder in der Datenbank gefunden wird.

So sicher sein, dass Zahlungsklasse wie folgt aussieht:

public class Payment 
{ 
    [Key] 
    public int Id {get; set;} 
    public bool Status {get; set;} 
} 

Und Ihre Eingabe Logik könnte wie folgt aussehen:

Payment payment = null; 
using (var ts = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(1, 0, 0, 0))) 
{ 
    using (var context = new DBContext()) 
    { 
     context.Database.Log = s => { System.Diagnostics.Debug.WriteLine(s); }; 
     payment = context.Payments.Find(orderId); 
     if(payment != null) 
     { 
      payment.Status = true; 
      context.Entry(payment).State = System.Data.EntityState.Modified;  
     } 
     else 
     { 
      context.Payments.Add(new Payment(){ 
       Status = true 
      }); 
     } 
     context.SaveChanges(); 
    } 
    ts.Complete(); 
} 

Hinzugefügt Transaktionsbereich sicher sein, dass es richtig ist Öffnen und Schließen und SQL-Abfrageprotokollierung zum Debug-Fenster hinzugefügt.

+0

Es ändert immer noch nicht den Status der Zahlung. Es erreicht die "if" -Anweisung und nicht die "else", aber es ändert nicht den Zustand. Die Bestell-ID ist korrekt, aber aus irgendeinem Grund wird diese Zahlung nicht aktualisiert ... – Pierre

+0

Vielleicht führen Sie Ihren Code in der Transaktion aus und nicht zu committen? Versuchen Sie, den DB-Kontext in TransactionScope wie im folgenden Beispiel zu umbrechen. Und prüfen Sie die SQL-Abfrage, die von EF generiert wurde, indem Sie ihre Protokollierungsmechanismen verwenden. – aleha

3

Der Grund all dieser Fehler ist, weil entweder das Payment-Objekt nie an den DBContext angehängt ist oder die orderId nicht mit der PK in der Payments-Tabelle übereinstimmt. Damit SaveChanges() tatsächlich funktioniert, muss das Objekt, das Sie ändern, vom DBContext überwacht werden, und nicht EntityState auf Modified festgelegt sein. Auch scheinen all diese Beispiele grob überkompliziert zu sein.

using (var db = new DbContext()) 
{ 
    // make sure you have the right column/variable used here 
    var payment = db.Payments.FirstOrDefault(x => x.Id == orderId); 

    if(payment == null) throw new Exception("Invalid id: " + orderId); 

    // this variable is tracked by the db context 
    payment.Status = true; 

    db.SaveChanges(); 
} 
+0

Ich habe überprüft, dass die orderId tatsächlich der richtige Wert für die Zahlungs-ID ist, die ich ändern möchte. Ich habe Ihren Code ausprobiert, aktualisiert diesen Eintrag jedoch nicht. Wenn ich diesen Code durch einen "neuen Eintrag zu Zahlung hinzufügen" ersetze, funktioniert der Code einwandfrei, der Code wird also ausgeführt, aber es werden keine Änderungen bei der Aktualisierung des Eintrags vorgenommen. – Pierre

+0

@Pierre Welche Version von Entity Framework verwenden Sie? Und läuft dieser Code innerhalb einer Transaktion auf einer beliebigen Ebene? –

+0

Entity Framework: v4.0.30319. Ich verwende keine Transaktionen. – Pierre

0

Wenn Sie nur Ihre Entität-ID haben, sagte nur tun, wie Ali Golshani. Aber wenn Sie bereits an das Unternehmen zu haben und wollen einfach nur aktualisieren, können Sie auf diese Weise tun:

public void Update(Payment payment, int orderId) 
    { 
     //first find the entity to update 
     Payment oldEntity = DbSet.Find(orderId); 

     //detach this entity from the DbSet 
     Db.Entry(oldEntity).State = EntityState.Detached; 

     //set the state from the entity that you just received to modified 
     Db.Entry(obj).State = EntityState.Modified; 
    } 

Detaching vermeidet die Fehlermeldung: „Anbringen ein Unternehmen schlug fehl, da eine andere Einheit des gleichen Typs bereits den gleichen Primärschlüssel hat Wert".

Ich hoffe, dass es hilft.

Verwandte Themen