4

私も同様の質問をしましたが、この問題を解決するためにそこにあったアイデアをあきらめたので、代わりにこれをきちんと解決するための手助けをしたいと思います。

私はテーブルを持っています

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()の順列をたくさん試しましたが、辞書が必要だと文句を言いますが、キーごとに複数の値が必要です。何か案は?

何か案は?ありがとう!

4

1 に答える 1

3

三項関係はバイナリ関連に置き換えることができますが、置き換え後に新しいエンティティが表示されます(三項関係タイプの削除)。あなたの場合は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)

これは、考えられる1つのアプローチのスケッチにすぎないことに注意してください。多くの詳細は問題のドメインによって異なり、本番環境の準備が整う前に微調整する必要があります:)-egcascades。

AsTernaryAssociationを使用したことはありませんが、興味深いようです。後で調査します。インスピレーションをありがとうございます:)。

編集:3値の関連付けは、わずかに異なるマッピング(composite-elementを使用)によって実装できますが、追加のエンティティがあります-この場合、コンポーネントとしてマッピングされる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では成功しません。

于 2011-05-19T20:23:41.703 に答える