我问了一个类似的问题,但我已经放弃了我在那里解决这个问题的想法,所以我希望能以一种巧妙的方式帮助解决这个问题。
我有桌子
Image - (Id, Name, RelativeFilePath)
ImageFilter - (Id, Type)
ImageContext - (Id, Name, ...)
ImageContextImage - (Id, ImageContextId, ImageId, ImageFilterId)
数据示例:
ImageContextImage Id ImageContextId ImageId ImageFilterId
1 1 1 1
2 1 1 2
3 2 1 1
4 3 2 1
如您所见,上下文中的图像可以应用多个过滤器。
我的所有实体都很简单,除了上面的这个映射。目前我已经
了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
以上很容易映射,但是对于每个图像,我会得到多个ImageContextImage对象。我宁愿让ImageContextImage包含一个ImageFilter列表,这样我就可以简单地遍历该集合。我已经尝试了很多AsTernaryAssociation()的排列,它抱怨我需要一个字典,但我想要每个键有多个值!有什么想法吗?
有什么想法吗?谢谢!
答案 0 :(得分:2)
三元关联可以用二元关联替换,但替换后会出现一个新实体(Removing Ternary relationship types)。在你的情况下是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)
请注意,这只是一种可能方法的草图。许多细节取决于您的问题域,必须在准备生产之前进行调整:) - egcascades。
我从未使用过AsTernaryAssociation,但似乎很有趣。我稍后会进行调查,谢谢你的灵感:)。
编辑: 三元关联可以通过稍微不同的映射(使用复合元素)来实现,但是仍然有其他实体 - 在这种情况下映射为组件的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没有成功。