2016-06-26 21 views
0

Ich habe eine ziemlich einfache Auktion-ähnliche Anwendung. Mit EF 6.x und bekomme eine Menge seltsames Verhalten beim Versuch, ein Kind (Bid) von der Eltern (Listing) zu löschen. Ich lösche Entitäten mit ähnlichen Arten von Beziehungen an anderer Stelle in meiner Anwendung ohne Probleme. Die beteiligten Einrichtungen:Entity Framework 6.x kann eine angefügte Entität in einer Beziehung nicht entfernen

public class Listing { 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int ListingID { get; set; } 

    [Required] 
    public bool Active { get; set; } 

    [Required] 
    [StringLength(128)] 
    public string UserID { get; set; } 

    [ForeignKey("UserID")] 
    public ApplicationUser User { get; set; } 

    public List<Bid> Bids { get; set; } 

    public Listing() { 
     User = new ApplicationUser(); 
     Bids = new List<Bid>(); 
    } 
} 

public class Bid { 
    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public int BidID { get; set; } 

    [Required] 
    public decimal Amount { get; set; } 

    [Required] 
    public DateTime Created { get; set; } 

    [Required] 
    [StringLength(128)] 
    public string UserID { get; set; } 

    public int ListingID { get; set; } 

    [ForeignKey("UserID")] 
    public ApplicationUser User { get; set; } 

    [ForeignKey("ListingID")] 
    public Listing Listing { get; set; } 

    public Bid() { 
     User = new ApplicationUser(); 
     Listing = new Listing(); 
    } 
} 

public class ApplicationUser : IdentityUser { 
    public List<Listing> Listings { get; set; } 

    public List<Bid> Bids { get; set; } 

    public ApplicationUser() { 
     Listings = new List<Listing>(); 
     Bids = new List<Bid>(); 
    } 
} 

In diesem Zusammenhang bin ich die Gebote durch den Benutzer abfragt und Entfernen von ihnen:

public bool RemoveBids(string offenderUserID) { 
    using (var db = new MyDbContext()) { 
     var bids = db.Bids 
      .Include(l => l.Listing) 
      .Where(x => x.UserID == offenderUserID && x.Listing.Active == true); 

     foreach (var bid in bids) { 
      bid.User = null; 
      bid.Listing = null; 
      db.Bids.Remove(bid); 
      db.Entry(bid).State = EntityState.Deleted; 
     } 

     return db.SaveChanges() == 1 ? true : false; //exception on SaveChanges() 
    } 
} 

Bis ich die bid.Listing nulled, bekam ich einen DbEntityValidationException den Spruch Felder für das Listing sind erforderlich. Beim Durchsuchen im Debugger wird angezeigt, dass EF versucht, neue Entitäten zu bid.User und bid.Listing hinzuzufügen. Verrückt ... aber OK. Ich ging weiter mit und endete mit dem, was Sie oben sehen ... was zu einem anderen xxx von:

Das Feld UserName erforderlich ist.

Benutzername ist in IdentityUser (AspNetUsers-Tabelle) als Teil von Identity Framework.

Es ist immer noch versucht, einen ApplicationUser ... irgendwie irgendwo hinzuzufügen? Nirgends in dem Graphen, den ich oben abgefragt habe, gibt es ein ApplicationUser-Objekt. Ich sehe es einfach nicht.

Bei der Überprüfung der Tabellen werden die Felder genauso angezeigt wie die obigen Elemente.

Dies ist mein erstes nicht-triviales Code-First-Projekt. Ich habe an einigen ziemlich großen DB-First-Projekten mit Edmx-Modellen gearbeitet und mich nie daran erinnert, so viele Hindernisse und seltsame "Gotchas" zu treffen. Die meisten Dinge schienen einfach zu funktionieren. Soll ich das Ding einfach umwandeln? Ich habe zu viel Zeit mit etwas so Einfachem verschwendet, wie es ist. Ich möchte EF mögen. Ich mag die Idee davon ... aber fühle mich nach Tagen der Fehlersuche nicht besonders produktiv.

Vielen Dank im Voraus.

Antwort

1
public Bid() { 
    User = new ApplicationUser(); 
    Listing = new Listing(); 
} 

public Listing() { 
    User = new ApplicationUser(); 
    Bids = new List<Bid>(); 
} 

EDIT. Der obige Code ist einfach falsch. Entfernen Sie diese Initialisierer. Sie sollten nur für Sammlungen existieren. Der Grund für diese bizarren Fehler liegt darin, dass Sie jedes Mal, wenn Sie ein Bid oder Listing Objekt laden, brandneue Objekte erstellen, denen die erforderlichen Parameter fehlen. Wenn Sie also saveganges aufrufen, landen Sie bei EF und beschweren sich, dass bestimmte erforderliche Parameter fehlen .

Ich sehe dies zunächst als eine Eigenschaft der Bid Klasse.

public int ListingID

Aber dann haben Sie ...

bid.Listing = null;

Logisch, das macht keinen Sinn machen. In der ersten Zeile des Codes sagen Sie, dass die Eigenschaft Listing für jedes Gebot erforderlich ist. Aber indem Sie es auf null setzen, sagen Sie, dass "diese Auflistung für dieses Gebot nicht erforderlich ist".

Ich denke, Sie können einfach die Zeilen des Codes entfernen, wo Sie die Navigationseigenschaften auf Null setzen, da sie nichts erreichen, da Sie nur das Objekt Bid sowieso löschen.

+0

Ich habe versucht, (versucht, oben zu erklären) - wenn ich Bid.Listing nicht auf Null setzen, fügt EF eine neue Auflistung mit einer ID von 0, und versucht dann, es auf SaveChanges einzufügen .. ., die eine Validierungsausnahme für alle erforderlichen Listing-Felder auslöst. –

+0

Was ist der Zweck dieser Codezeile? 'db.Entry (bid) .State = EntityState.Deleted;' Versuchen Sie auch, das zu entfernen. –

+0

Ich habe, und der Fehler bleibt gleich. Fügen Sie das erst hinzu, nachdem Sie es als Vorschlag für einen anderen Beitrag gesehen haben. –