Domanda

Mi stavo solo bagnando i piedi con alcune convenzioni di Fluent NHibernate AutoMap e mi sono imbattuto in qualcosa che non riuscivo a capire.Presumo che non sto cercando nel posto giusto...Fondamentalmente cercando di imporre NOT-NULL sul lato "molti" della relazione uno a molti.Sembra che, utilizzando l'automapping, la proprietà genitore Id sia sempre nullable nel database.

Ho fatto qualche ricerca su StackOverFlow e ho trovato domande simili, ma nulla relativo ad AutoMapping e Convenzioni (a meno che non me ne sia accorto).

Esempio veloce...

public class Group    // One Group
{
    public Group() { this.Jobs = new List<Job>(); }
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Job> Jobs { get; protected set; }
}

public class Job    // Has many Jobs
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }

    // Trying to make this field not-nullable in the database.
    public virtual Group Group { get; set; }
}

Pensavo che avrei potuto creare una convention come...

public class OneToManyConvention : IHasOneConvention
{
    public void Apply(IOneToOneInstance instance)
    {
        // Nullable() isn't a valid method...
        instance.Not.Nullable();   
    }
}

Ma sembra che IOneToOnInstance non abbia un metodo Nullable().Posso farlo se creo un file di mappa per Job, ma cercando di evitare qualsiasi file di mappa e attenermi alla mappatura automatica.

Mi sono imbattuto in questo collegamento nell'elenco dei gruppi Fluent descrivendo qualcosa di simile.

Che descrive qualcosa del genere...

public class NotNullPropertyConvention : IPropertyConvention
{
    public bool Accept(IProperty target)
    {
            return true;
    }
    public void Apply(IProperty target)
    {
            target.Not.Nullable();
    }
}

Ma ciò solleva le domande di...1) Come determinare che IProperty sia un lavoro (o qualsiasi proprietà figlio che sia un collegamento al genitore)

2) In quella pagina è stato menzionato che l'utilizzo di questo avrebbe sovrascritto le mie sostituzioni manuali, ad es.se un collegamento a una proprietà molto specifica doveva essere NULL.Quale sarebbe un problema (se è ancora un problema, ma non è possibile eseguire il test senza prima capire il punto 1)

Qualche idea su questo?Mi sto perdendo qualcosa?



Aggiornamento 1

Ancora niente da fare.Anche quanto segue non impone ancora Not-Nullable nello schema del database...

public class FluentConvention : IPropertyConvention
{
    public void Apply(IPropertyInstance instance)
    {
        instance.Not.Nullable();
    }
}

Lo stesso vale per tutti gli altri campi...
/alzata di spalle

Qualche idea?



Aggiornamento 2

Anche se questa non è la risposta che stavo cercando, ho trovato una soluzione...Stavo utilizzando l'assembly NHibernate Validator e all'interno di quell'assembly c'è un attributo [NotNull].Se decorassi la mia classe con l'attributo Validator e associassi ValidationEngine a NHibernate prima della creazione dello schema, contrassegnerebbe la colonna del database FK come Not-Nullable.

public class Job    // Has many Jobs
{
    public virtual Guid Id { get; set; }
    public virtual string Name { get; set; }

    [NHibernate.Validator.Constraints.NotNull]
    public virtual Group Group { get; set; }
}

Se qualcuno ha bisogno del codice completo per l'inizializzazione di NHibernate + ValidationEngine, fatemelo sapere.Sto ancora cercando un modo per farlo utilizzando il percorso della pura convenzione di mappatura, se qualcuno ha qualche informazione...

Grazie!

È stato utile?

Soluzione

Puoi sovrascrivere le proprietà mappate automaticamente come parte della tua AutoMap in Fluenttly.Configure().

Quindi puoi fare questo:

.Override<Job>(map => map.References(x => x.Group).Not.Nullable())

Tuttavia non è esattamente conveniente se hai molte classi che ne hanno bisogno.

Modificare: Puoi anche specificare l'override in una classe che implementa IAutoMappingOverride in questo modo:

    public class JobMappingOverride : IAutoMappingOverride<Job>
    {
            public void Override(AutoMapping<Job> mapping)
            {
                    mapping.References(x => x.Group).Not.Nullable();
            }
    }

e includerlo in questo modo:

    .UseOverridesFromAssemblyOf<JobMappingOverride>()

Ciò manterrebbe la tua configurazione fluida un po' più pulita.

Altri suggerimenti

Sembra che IPropertyConvention viene chiamato solo su proprietà semplici delle tue classi.Se la tua proprietà fa riferimento a un'altra classe, devi utilizzare IReferenceConvention pure.

Prova questo:

public class FluentConvention : IPropertyConvention, IReferenceConvention  
{      
    public void Apply(IPropertyInstance instance)
    {          
        instance.Not.Nullable();      
    }

    public void Apply(IManyToOneInstance instance)
    {
        instance.Not.Nullable();
    }
}      
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top