4

私は次のデータ構造を持っています:

+---------+
|Resume   |
+---------+
|Id (PK)  |
|IsActive |
|...      |
|..       |
|.        |
+---------+

+--------------------+
|Resume_Translation  |
+--------------------+
|ResumeId (PK, FK)   |
|Language (PK)       |
|Title               |
|Description         |
|...                 |
|..                  |
|.                   |
+--------------------+

したがって、2つの結合されたテーブルを使用してこのようなデータを取得できます。

+----------------------------------------------------------+
|Id | IsActive | ResumeId | Language | Title | Description |
+----------------------------------------------------------+
|1  | true     | 1        | 'fr'     | 'One' | 'One desc'  |
|1  | true     | 1        | 'pl'     | 'Raz' | 'Raz Opis'  |
|2  | true     | 2        | 'fr'     | 'B'   | 'bla bla'   |
|3  | true     | 3        | 'fr'     | 'C'   | 'C bla bla' |
+----------------------------------------------------------+

Resume私のドメインの観点から、私はエンティティのみを気にします。現在の翻訳を持つエンティティは1つしかないためResume、コレクションを持つエンティティは必要ありません。Resume_TranslationsResume

public class Resume
{
    public virtual int Id{ get; protected internal set; }

    public virtual string Language { get; protected internal set; }

    public virtual string Title { get; protected internal set; }

    public virtual string Description { get; protected internal set; }

    public virtual bool IsActive { get; protected internal set; }
}

FluentNHibernateを使用した現在のマッピングは次のとおりです。

public class ResumeMap : ClassMap<Resume>
{

    public ResumeMap()
    {
        Table("Resume");
        Id(x => x.Id);
        Map(x => x.IsActive);
        // other properties
        Join("Resume_Translation", m =>
                        {
                            m.Fetch.Join();
                            m.Map(x => x.Language).Length(5);
                            m.Map(x => x.Title).Length(100);
                            m.Map(x => x.Description).Length(200);
                        });
    }
}

WHERE述語に履歴書のIDと必要な言語を渡すだけで、問題なくリポジトリから必要なものを取得できます。

ただし、値の挿入と更新に問題があります。

私の質問は、NHibernateが現在のエンティティのレコードを更新するのではなく、Resume_Translationテーブルにのみ新しいレコードを挿入するマッピングをどのように定義するかです。

したがって、私が達成したいのは、データベースに次のレコードがある場合です。

|2  | true     | 2        | 'fr'     | 'B'   | 'bla bla'   |

結合はテーブル間の1対1の関係に適しているため、これをエンティティに取り込み、言語と翻訳を変更すると、nhibernateが更新を実行し、理解できます。異なる言語と翻訳で同じIDを持つ新しいエンティティを追加しようとすると、nhibernateはキーがすでに存在するというエラーを生成し、それも理解しています。

ですから、確かに私は間違った道を進んでいますが、誰かが私が望むマッピングを達成する方法について正しい解決策を教えてくれるなら、私は大いに感謝します。

別の質問ですが、ビジネスの観点から、エンティティとその翻訳をどのように処理しますか?

よろしくお願いします。

トーマス

4

3 に答える 3

2

ステファンは正しい方向に進んでいます。私は彼の提案を微調整して、更新をはるかに簡単にする双方向の関連付けを行いました。このアプローチの1つの欠点は、NHibernateがResumeテーブルキーをResumeTranslation行に適切に割り当てるように、挿入時にResumeTranslationインスタンスのResumeプロパティを手動で割り当てる必要があることです。したがって、マッピングしている関連付けを考えると、FluentNHでは次のようになります。

public class ResumeTranslation
{
    public virtual string Title { get; protected internal set; }

    public virtual string Description { get; protected internal set; }

             //Needed for bi-directional association:
    public virtual Resume Resume { get; set; }
}


public class ResumeTranslationMap : ClassMap<ResumeTranslation>
{

    public ResumeTranslationMap()
    {
        Table("ResumeTranslation");
        CompositeId()
            .KeyReference(kp => kp.Resume, "ResumeId")
            .KeyProperty(kp => kp.Language, "Language");

        Map(x => x.Title);
        Map(x => x.Description);
    }
}

public class ResumeMap : ClassMap<Resume>
{

    public ResumeMap()
    {
        Table("Resume");
        Id(x => x.Id);
        Map(x => x.IsActive);
        // other properties

        HasMany(c => c.Translations)
            .Inverse()
            .KeyColumn("id") //May not be required but here for reference
            .Cascade.All();
    }
}
于 2011-07-12T15:42:05.023 に答える
2

私には1対多の関係のようです。個人的には、 Resumeオブジェクト内にResumeTranslationオブジェクトのコレクションがあります。次に、これを標準の1対多にマッピングします。

次に、を表す別のプロパティActiveResumeTranslationResumeエンティティに追加できますcurrent translation

于 2011-07-12T13:25:41.233 に答える
2

言語をキーとして使用して、辞書を使用するのはどうですか?

public class ResumeTranslation
{
    public virtual string Title { get; protected internal set; }

    public virtual string Description { get; protected internal set; }
}

public class Resume
{
    public virtual int Id{ get; protected internal set; }

    // language is the key to the translation
    // you may even want to hide the dictionary from the public interface of
    // this class and only provide access to a "current" language.
    public virtual IDictionary<string, ResumeTranslation> Translations { get; private set; }

    public virtual bool IsActive { get; protected internal set; }
}

それに応じて、複合要素を使用してマップしmapます(申し訳ありませんが、私は流暢なものを使用していないので、どのように見えるかを聞かないでください)。データベースモデルと完全に一致します。

于 2011-07-12T15:18:18.003 に答える