Тернарная ассоциация может быть заменена двоичными ассоциациями, но после замены появится новая сущность ( Удаление тернарных типов отношений ). Это объект ImageContextImage в вашем случае, и сложная часть состоит в том, чтобы найти лучшее имя для такого объекта. Ваш пример очень близок к этой замене.
Объект ImageContextImage:
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; }
и это отображение:
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:
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<ImageContextImage> ImageContextImageList { get; set; }
и его отображение:
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");
Соответствующая схема базы данных немного отличается:
ImageContextImage(Id, Image_id, Context_id)
и для связи «многие ко многим» необходимо создать новую таблицу связей:
ImageFilterToImageContextImage(ImageContextImage_id, ImageFilter_id)
Обратите внимание, что это только набросок одного возможного подхода. Многие детали зависят от вашей проблемной области и должны быть настроены, прежде чем она будет готова к производству :) - например, .cascades.
Я никогда не использовал AsTernaryAssociation, но это кажется интересным. Я буду исследовать это позже, спасибо за вдохновение:).
EDIT:
Тернарная ассоциация может быть реализована с помощью немного другого отображения (с использованием составного элемента), но есть еще дополнительная сущность - ImageContextImage, которая в этом случае отображается как компонент:
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 может быть расширен с помощью этих методов, чтобы упростить задачу:
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();
}
Нет успеха с AsTernaryAssociation.