2009-05-04 1 views
0

Ich habe eine Menge Probleme mit der Kaskadierung von Löschungen durch eine HasAndBelongsToMany-Beziehung mit Castle ActiveRecord/NHibernate.Kaskadierung mit Castle ActiveRecord HasAndBelongsToMany's

Ich habe Fotos, die viele Tags haben und gehören. Sie sind mit einer Tabelle namens PhotoHasTag verbunden, die nur eine PhotoId und eine TagId hat. Wenn ich ein Foto lösche, möchte ich, dass alle zugehörigen PhotoHasTag-Einträge gelöscht werden und alle verwaisten Tags ebenfalls gelöscht werden.

Im Moment habe ich mein Photo Klasse Setup etwas wie folgt aus:

[ActiveRecord(Table="Photo")] 
    public class Photo 
    { 
     [PrimaryKey(Column = "photoId", Generator = Castle.ActiveRecord.PrimaryKeyType.Identity)] 
     public virtual int Id { get; set; }  

     [HasAndBelongsToMany(Table="PhotoHasTag",ColumnKey="photoId",ColumnRef="tagId",Lazy=true,Cascade=ManyRelationCascadeEnum.AllDeleteOrphan)] 
     public virtual IList<Tag> Tags { get; set; } 
    } 

Und mein Tag-Klasse ist Setup so ziemlich die gleiche Art und Weise:

[ActiveRecord(Table="Tag")] 
    public class Photo 
    { 
     [PrimaryKey(Column = "tagId", Generator = Castle.ActiveRecord.PrimaryKeyType.Identity)] 
     public virtual int Id { get; set; } 

     [HasAndBelongsToMany(Table = "PhotoHasTag", ColumnKey = "tagId", ColumnRef = "photoId", Lazy = true)] 
     public IList<Photo> Photos { get; set; } 
    } 

Wenn ich versuche, Fotos zu entfernen, habe ich am Ende up bekommen einen Fehler von SQL Server:

The DELETE statement conflicted with the REFERENCE constraint "PhotoHasTag_FK1". 

Ich kann dies umgehen in SQL Server von sett Wenn Sie die Löschregel für den Key to Cascade ausführen, wird nur der PhotoHasTag gelöscht. Wenn verwaiste Tags vorhanden sind, verbleiben sie immer noch in der Datenbank.

Ich erwäge, einen Trigger zu schreiben, der sich um die übrig gebliebenen Tags kümmert, aber ich wäre viel glücklicher, wenn es eine Möglichkeit gäbe, meine ActiveRecord-Mappings einzurichten, so dass das Löschen kaskadiert.

Vielen Dank im Voraus, ich bin auf diesem für immer fest, so dass ich jede und alle Hilfe zu schätzen wissen!

Antwort

2

Sie können wie so Kaskadenverhalten in den Attributen angeben:

[HasAndBelongsToMany(Table = "PhotoHasTag", Cascade=ManyRelationCascadeEnum.AllDeleteOrphan, ColumnKey = "tagId", ColumnRef = "photoId", Lazy = true)] 
public IList<Photo> Photos { get; set; } 

Die API Dokumentation ist wahrscheinlich hilfreicher.