2016-06-05 11 views
0

Ich habe diesen nützlichen Beitrag Entity Framework .Remove() vs. .DeleteObject() lesen, dass dies im Grunde sagt:EF Optional Navigations Kaskade nicht löschen

Wenn die Beziehung ist optional, dh der Fremdschlüssel, der auf das übergeordnete vom Kind bezieht sich in der Datenbank ermöglicht NULL Dieser Foreign-Wert wird auf null gesetzt, und wenn Sie SaveChanges aufrufen, wird dieser NULL-Wert für die childEntity in die Datenbank geschrieben (dh die Beziehung zwischen den beiden wird entfernt). Dies geschieht mit einer SQL UPDATE-Anweisung. Es gibt keine DELETE-Anweisung.

Bedeutet dies, dass selbst bei der Option CascadeOnDelete optionale Beziehungen nicht kaskadiert werden? Ich möchte, dass das ImageFile Kind gelöscht wird, wenn das EditPendingApprovalSong gelöscht wird, in dem Moment, in dem es nur die fremde ID auf null setzt.

public class EditPendingApprovalSong 
{ 
    public int Id { get; set; } 
    ... 
    public virtual ImageFile Image { get; set; } 
} 

public class ImageFile 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<EditPendingApprovalSong>().HasOptional(x => x.Image).WithOptionalPrincipal().WillCascadeOnDelete(true); 

    base.OnModelCreating(modelBuilder); 
} 

[HttpPost] 
[ValidateAntiForgeryToken] 
[Authorize(Roles = "Admin")] 
public ActionResult RejectEdit(ApproveEditDto approveEditDto) 
{ 
    ... 
    var editPendingApprovalSong = _editPendingApprovalSongService.GetEditPendingApprovalSong(approveEditDto.Id); 

    _editPendingApprovalSongService.Delete(editPendingApprovalSong); 

    return RedirectToAction("Index"); 
} 

//Delete method that service calls 
public virtual void Delete(T entity) 
{ 
    _context.Set<T>().Remove(entity); 
    Save(); 
} 

Mit meiner anderen Beziehungen z:

modelBuilder.Entity<EditPendingApprovalSong>().HasMany(x => x.BuyLinks).WithOptional().WillCascadeOnDelete(true);

diese funktionieren und das Kind Objekte löschen, wie sie sollten. Meine Frage ist, muss ich eine der Navigation zu erforderlich ändern, damit es richtig kaskadiert oder mache ich etwas anderes falsch?

Die SQL-Anweisungen EF erzeugt, können Sie es tut die Update-Anweisung sehen, welche nicht das, was ich will:

exec sp_executesql N'UPDATE [dbo].[ImageFiles] 
SET [EditPendingApprovalSong_Id] = NULL 
WHERE (([Id] = @0) AND ([EditPendingApprovalSong_Id] = @1)) 
',N'@0 int,@1 int',@0=6,@1=4 

exec sp_executesql N'DELETE [dbo].[EditPendingApprovalSongs] 
WHERE ((([Id] = @0) AND ([Song_Id] = @1)) AND ([User_Id] = @2))',N'@0 int,@1 int,@2 nvarchar(128)',@0=4,@1=1,@2=N'd40b1bdc-c5e9-4c74-bacd-6e6723e188d5' 
+0

Aber ist das 'ImageFile' nicht durch die zweite Anweisung gelöscht? Sie werden keine Löschanweisung für "ImageFile" mit kaskadiertem Löschen sehen. –

+0

@GertArnold Anstatt es zu löschen, wird der Fremdschlüssel auf Null aktualisiert und ich weiß nicht warum. Die zweite Anweisung löscht es nicht, obwohl es auf meinen anderen vielen zu vielen Sammlungen funktioniert. –

+0

OK, nur um sicher zu sein. –

Antwort

0

Ich habe Tests mit anderen Klassen und es funktionierte (gründlicher hätte sein sollen, bevor Buchung). Ich habe den EditPendingApprovalSong über eine Elternklasse hinzugefügt, aber als ich diese Klasse löschte, habe ich sie nicht über diesen Elternknoten entfernt. Deshalb hat EntityFramework nicht gemacht, was ich wollte.

Verwandte Themen