2016-11-09 1 views
0

Ich habe eine Frage bezüglich der Aktualisierung bestehender Benutzer mit neuen Daten mithilfe von EntityFramework und Domänenmodellen. Oder eigentlich eher ein Problem.EntityFramework speichert keine neuen Daten für Entität

Wenn Sie einen neuen Auftrag an einen Benutzer hinzufügen, nach Order zu einem OrderEntity Zugabe es dann zu den UserEntity Umwandeln und es in die Datenbank persistierenden wird die angegebene Reihenfolge nicht gespeichert.

So haben wir ein IUserModel hier:

public interface IUser 
{ 
    int ID { get; } 
    List<IOrder> Orders { get; } 
} 

Und ein Unternehmen UserEntity hier:

public class UserEntity 
{ 
    int ID { get; set; } 
    public List<OrderEntity> Orders { get; set; } 
} 

Wir haben ein Service PersistenceService hier genannt:

public async Task<bool> UpdateInformation(IUser user) 
{ 
    using (var databaseContext = new DatabaseContext()) 
    { 
     var userEntity = await database.Users.Include(u => u.Orders) 
          .FirstOrDefaultAsync(x => x.ID == user.ID); 

     userEntity.Orders = user.Orders.ToEntity(); // Extension (convert to entity)   
     databaseContext.Entry(userEntity).State 
         = EntityState.Modified; // Do we need this? 
     databaseContext.Entry(userEntity.Orders).State 
         = EntityState.Modified; // Do we need this? 

     await databaseContext.SaveChangesAsync(); 
    } 
} 

Tabellen in der Datenbank so aussehen:

Orders          User 
--------         -------- 
int ID          int ID 
Money Price 
int UserId -- foreign key to user that owns this order  

Edit: An einem gewissen Punkt, wenn ein Benutzer einen Auftrag wir nennen dies schaffen machen:

public async void AddNewOrder(IOrder order) 
{ 
    IUser user = GetActiveUser(); // This just return an IUser 
    var persistenceService = GetPersistenceService(); // returns instance of persistence service 

    user.Orders.Add(order); 
    await persistenceService.UpdateInformation(user); 
} 

bearbeiten 2016.09.11: Nach mehr Debugging, es sieht wie die Zeile:

await persistenceService.UpdateInformation(user); 

Wird nie zurückgegeben, dies ändert sich nicht, wenn Sie den Code ändern, um die Synchronisierung auszuführen auch nicht. Es ist also kein Threading-Problem.

+0

Wie rufen Sie diese Methode? Sie müssen ihm Zeit geben, damit SaveChangesAsync funktioniert. Haben Sie versucht, UpdateInformation(). GetAwaiter(). GetResult()? –

+0

Wie DavidG sagte, scheinen Sie lediglich eine Bestellung zu aktualisieren und nicht mit dem Benutzer zu verknüpfen. –

+0

In Ordnung - also habe ich eine Bearbeitung gemacht, um zu zeigen, wie eine Bestellung zum Benutzer hinzugefügt wird, auch @RicardoPeres hilft nicht, das Problem wird nicht durch synchrone Arbeit gelöst. – Nicholas

Antwort

1

Sie das Überschreiben der Auftragsliste in dieser Aussage:

userEntity.Orders = user.Orders.ToEntity(); // Extension (convert to entity) 

Ich bin mir ziemlich sicher, dass das, was Zeug vermasselt. Wenn Sie die Zeile zu ändern:

userEntity.Orders.AddRange(user.Orders.ToEntity()); 

Ich glaube, es sollte funktionieren. Dies fügt jedoch immer alle Bestellungen dem Kunden als neu hinzu. Wenn dies nicht gewünscht ist, können Sie eine Kombination aus Add- und Remove-Aufrufen verwenden, um die Orders-Sammlung zu aktualisieren, anstatt sie einfach hinzuzufügen. Aber um nur zu testen, ob es etwas speichert, können Sie einfach AddRange() für jetzt verwenden.

Darüber hinaus sollten Sie den Status der Entitäten nicht festlegen, es sei denn, Sie fügen sie an (was Sie nicht sind). So fallen diese Zeilen

+0

Ich glaube nicht, das dupliziert auch die Einträge in Orders - richtig? – Nicholas

+0

In diesem Fall reicht ein einfacher AddRange möglicherweise nicht aus, und ein etwas komplexerer Synchronisationsmechanismus ist möglicherweise erforderlich, aber ich denke, dass das Überschreiben der Orders-Eigenschaft das Problem verursacht. Fügen Sie einfach die neuen Werte hinzu, aktualisieren Sie die vorhandenen und entfernen Sie die entfernten. Ich bin mir ziemlich sicher, dass es dann funktionieren wird. Wenn Sie die AddRange zuerst ausführen, erhalten Sie Duplikate, aber es ist ein einfacher Weg zu sehen, ob die Aufträge überhaupt gespeichert werden. – Robba

+0

Hey @Robba, ich habe deine Lösung versucht, aber das hat auch nicht geholfen, keine Änderung. Das Problem ist, dass databaseContext.SaveChanges(); gibt nie zurück – Nicholas

0

Das Problem ist, dass die Aktualisierung des Benutzers wird nicht helfen. Sie müssen das Aktualisieren der Aufträge erzwingen, die einen Verweis auf den Benutzer IMO enthalten. Füge sie nicht hinzu, erzwinge Update, setze den Status im DbEntry.

+0

Hallo, danke für deine Antwort. Ich debuggte etwas weiter und sieht so aus, als ob die Zeile databaseContext.SaveChanges() nie zurückkehrt (weder asynchron noch synchron) – Nicholas

+0

Kann es sich um einen Transaktions-Deadlock handeln? –

+0

Können Sie die SQL nicht überwachen, indem Sie ein ctx.Database.Log + = Console.WriteLine hinzufügen? –

Verwandte Themen