Domanda

Ho fatto una domanda simile, ma ho rinunciato all'idea che ho avuto lì per risolvere questo problema, quindi vorrei che un po 'di aiutarla a risolvere questo in modo ordinato.

Ho tavoli

Image - (Id, Name, RelativeFilePath)
ImageFilter - (Id, Type)
ImageContext - (Id, Name, ...)
ImageContextImage - (Id, ImageContextId, ImageId, ImageFilterId)
.

Esempio di dati:

ImageContextImage      Id        ImageContextId         ImageId        ImageFilterId
                       1         1                      1              1
                       2         1                      1              2
                       3         2                      1              1
                       4         3                      2              1
.

Come puoi vedere, un'immagine in un contesto può avere diversi filtri applicati.

Tutte le mie entità sono molto semplici, tranne questa mappatura di quanto sopra.Attualmente ho

ImageContext
    public virtual int Id
    public virtual string Name
    public virtual IList<ImageContextImage> Images

ImageContextImage
    public virtual int Id
    public virtual ImageContext Context
    public virtual Image Image
    public virtual ImageFilter ImageFilter
.

Quanto sopra è molto facile da mappare, ma per ogni immagine, ottengo quindi più oggetti ImageContextimage.Preferirei avere l'imagecontextimage contiene un elenco di imagefilter, in modo che io possa semplicemente iterare attraverso quella raccolta.Ho provato un sacco di permutazioni dell'Asternassociazione () e si lamenta di aver bisogno di un dizionario, ma voglio più valori per chiave!Qualche idea?

Qualche idea?Grazie!

È stato utile?

Soluzione

Associazione Ternario può essere sostituita con associazioni binarie ma una nuova entità apparirà dopo la sostituzione ( Rimozione dei tipi di relazione ternaria ). È l'entità ImageContextimage nel tuo caso e la parte difficile è trovare il miglior nome per tale entità. Il tuo esempio è molto vicino a questa sostituzione.

ImageContextMage Entity:

public virtual int Id { get; set; }
public virtual Image Image { get; set; }
public virtual ImageContext Context { get; set; }
public virtual IList<ImageFilter> Filters { get; set; }
.

Ed è la mappatura:

Id(x => x.Id);
References(x => x.Image);
References(x => x.Context);
HasManyToMany(x => x.Filters); // filters are referenced via many-to-many relation
.

ImageContext Entity:

public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<ImageContextImage> ImageContextImageList { get; set; }
.

Ed è la mappatura:

Id(x => x.Id);
Map(x => x.Name);
HasMany(x => x.ImageContextImageList)
    .Inverse(); // to aggregate all ImageContextImage that are fererencing this instnstance of ImageContext
    .KeyColumn("Context_id");
.

Lo schema del database corrispondente è leggermente diverso:

ImageContextImage(Id, Image_id, Context_id)
.

e la nuova tabella di associazione deve essere creata per le molte-a-numerose relazioni:

ImageFilterToImageContextImage(ImageContextImage_id, ImageFilter_id)
.

Nota che questo è solo uno schizzo di un possibile approccio. Molti dettagli dipendono dal tuo dominio problematico e devono essere modificati prima che sia pronto per la produzione :) - E.G.Cascades.

Non ho mai usato l'asternassociazione ma sembra interessante. Lo inventerò più tardi, grazie per l'ispirazione :).

Modifica: L'Associazione Ternary può essere implementata da una mappatura leggermente diversa (utilizzando elemento composito) ma c'è ancora entità aggiuntiva - ImageContextimage che è mappato come componente in questo caso:

public class ImageContext
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<ImageContextImage> ImageContextImageList { get; set; }

    public ImageContext()
    {
        ImageContextImageList = new List<ImageContextImage>();
    }
}

public class ImageContextMap : ClassMap<ImageContext>
{
    public ImageContextMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        HasMany(x => x.ImageContextImageList).Component(c =>
        {
            c.References(x => x.Image);
            c.References(x => x.Filter);
        }).Cascade.AllDeleteOrphan();
    }
}

public class ImageContextImage
{
    public virtual Image Image { get; set; }
    public virtual ImageFilter Filter { get; set; }
}
.

ImageContext Class può essere esteso da questi metodi per rendere le cose più semplici:

public virtual IEnumerable<Image> AssociatedImages
{
    get
    {
        return ImageContextImageList.Select(x => x.Image).Distinct().ToList();
    }
}

public virtual IEnumerable<ImageFilter> GetFilters(Image image)
{
    return ImageContextImageList.Where(x => x.Image == image).Select(x => x.Filter).ToList();
}
.

Nessun successo con l'asternassociazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top