2009-02-25 20 views
21

Come si "attiva" i salvataggi a cascata utilizzando AutoMap Persistence Model con Fluent NHibernate?Cascade Saves con Fluent NHibernate AutoMapping

Come in:

ho salvare la persona e il braccio deve anche essere salvati. Attualmente ricevo

"oggetto fa riferimento a un'istanza transiente non salvato - salva l'istanza transitorio prima di vampate di calore"

public class Person : DomainEntity 
{ 
    public virtual Arm LeftArm { get; set; } 
} 

public class Arm : DomainEntity 
{ 
    public virtual int Size { get; set; } 
} 

ho trovato an article on this topic, ma sembra di essere superata.

+0

Questo dovrebbe essere fatto usando una convenzione? –

risposta

13

Questo funziona con i nuovi bit di configurazione. Per ulteriori informazioni, vedere http://fluentnhibernate.wikia.com/wiki/Converting_to_new_style_conventions

//hanging off of AutoPersistenceModel  
.ConventionDiscovery.AddFromAssemblyOf<CascadeAll>() 


public class CascadeAll : IHasOneConvention, IHasManyConvention, IReferenceConvention 
{ 
    public bool Accept(IOneToOnePart target) 
    { 
     return true; 
    } 

    public void Apply(IOneToOnePart target) 
    { 
     target.Cascade.All(); 
    } 

    public bool Accept(IOneToManyPart target) 
    { 
     return true; 
    } 

    public void Apply(IOneToManyPart target) 
    { 
     target.Cascade.All(); 
    } 

    public bool Accept(IManyToOnePart target) 
    { 
     return true; 
    } 

    public void Apply(IManyToOnePart target) 
    { 
     target.Cascade.All(); 
    } 
} 
+0

Grazie per l'aggiornamento. –

+0

Grazie. In realtà ho usato l'esempio più breve di Kristoffers ma sono sicuro che anche questo funziona –

1

È inoltre possibile eseguire in cascata la convenzione predefinita per tutti i tipi. Ad esempio (utilizzando l'articolo collegato come punto di partenza):

autoMappings.WithConvention(c => 
    { 
    // our conventions 
    c.OneToOneConvention = o => o.Cascade.All(); 
    c.OneToManyConvention = o => o.Cascade.All(); 
    c.ManyToOneConvention = o => o.Cascade.All(); 
    }); 
3

Il metodo di convenzione Le firme sono cambiate. Per la nuova risposta che fa esattamente ciò che questa domanda chiede vedi THIS QUESTION.

13

aggiornato per l'utilizzo con la versione attuale:

public class CascadeAll : IHasOneConvention, IHasManyConvention, IReferenceConvention 
{ 
    public void Apply(IOneToOneInstance instance) 
    { 
     instance.Cascade.All(); 
    } 

    public void Apply(IOneToManyCollectionInstance instance) 
    { 
     instance.Cascade.All(); 
    } 

    public void Apply(IManyToOneInstance instance) 
    { 
     instance.Cascade.All(); 
    } 
} 
+1

Per "public void Apply (istanza IOneToManyCollectionInstance) ", trovo anche utile avere "instance.inverse();" oltre a "instance.Cascade.All()." – Antony

+0

Grazie a questo codice ha funzionato per me. –

+0

@Antony L'inverso ha fatto il trucco per me. Grazie! –

4

Il modo più semplice che ho trovato per fare questo per un intero progetto è quello di utilizzare DefaultCascade:

.Conventions.Add(DefaultCascade.All());  

Vai "The Simplest Conventions" sezione sul wiki, per questo, e un elenco di altri.

Ecco l'elenco dal Wiki:

Table.Is(x => x.EntityType.Name + "Table") 
PrimaryKey.Name.Is(x => "ID") 
AutoImport.Never() 
DefaultAccess.Field() 
DefaultCascade.All() 
DefaultLazy.Always() 
DynamicInsert.AlwaysTrue() 
DynamicUpdate.AlwaysTrue() 
OptimisticLock.Is(x => x.Dirty()) 
Cache.Is(x => x.AsReadOnly()) 
ForeignKey.EndsWith("ID") 

Una parola di avvertimento - alcuni dei nomi dei metodi della Wiki può essere sbagliato. Ho modificato il Wiki con quello che potevo verificare (ad esempio DefaultCascade e DefaultLazy), ma non posso garantire per il resto. Ma dovresti essere in grado di capire i nomi propri con Intellisense, se necessario.

+0

Mi piacerebbe vedere quel link, ma è morto – Joel

+0

@Joel: sembra che il nuovo wiki sia qui: https://github.com/jagregory/fluent-nhibernate/wiki/Conventions – RedGreenCode

Problemi correlati