1

ローカライズされたアプリケーションを構築しています。すべてのデータは異なる言語で利用可能である必要があります。ストレージモデルとして、Entity Frameworkよりもパフォーマンスが優れているため、Nhibernateを使用しようとしています。ルートノードをデータベースに保存してエンティティの一意のIDを取得し、言語ごとの子ノードを含む2番目のテーブル(ロケールテーブル)を作成します。

私のデータベーステーブルは次のようになります。

Country
   Int Id;
Country_Locale
   Int Id;
   Int CountryId;
   String LangCode;
   String Name;

City
   Int Id;
   Int CountryId;
City_Locale
   Int Id;
   Int CityId;
   String LangCode;
   String Name;

私の好みのエンティティは次のようになります

Country
  Int Id (from Coutry table)
  String LangCode (from locale table)
  String Name (from locale table)
  IList<City> Cities (Referenced to City entity)
City
  Int Id (From City table)
  String LangCode (from locale table)
  String Name (from locale table)
  Country Country (Referenced to Country entity)
  Int CountryId (From country table)

上記をマッピングすることはできませんが、それは私が好む構造の一種です。このマッピングをどのように行うことができますか、または他の提案があります。

**データベーステーブルのレイアウトを編集して、もう少し明確にしました。

4

3 に答える 3

1

別々のテーブルを使った最初の試みと同様のアプローチを取りましたが、最終的にはそれに固執し、非常にうまくいきました。Fluentマッピングファイル(Fluent NHibernateを使用しています)と、データベースからデータを取得するためのサンプルコードを次に示します。

using FluentNHibernate.Mapping;

namespace Core.Mapping
{    
    public class CountryMap : ClassMap<Country>
    {
        public CountryMap()
        {
            Id(x => x.Id);

            Map(x => x.IsoCode)
                .Length(2)
                .Not.Nullable();

            HasMany(x => x.Translations)
                .Fetch.Join()
                .Not.LazyLoad()
                .Cascade.AllDeleteOrphan();
        }
    }
}

国の翻訳は実際には別のクラス/テーブルとして保存されますが、これはあなたが探しているものとは正確には一致しませんが、最終的にはすべての翻訳が保存される1つのテーブルがあるため、非常にうまく機能します。Fluentマッピングクラスは次のとおりです。

using FluentNHibernate.Mapping;

namespace Core.Mapping
{
    public class CountryTranslationMap : ClassMap<CountryTranslation>
    {
        public CountryTranslationMap()
        {
            Id(x => x.Id);

            Version(x => x.LastModified);

            Map(x => x.Culture)
                .Length(2)
                .Not.Nullable();

            Map(x => x.Name)
                .Length(50)
                .Not.Nullable();

            References(x => x.Country);
        }
    }

}

カルチャまたはISOコード(ここではNHibernate QueryOver構文を使用しています)のいずれかによって国を取得するためのデータアクセス層からのいくつかの例を次に示します。

    public IList<Country> GetAll(string culture)
    {
        var countryLanguageValue = new CountryTranslation();

        IList<Country> results = UnitOfWork.CurrentSession.QueryOver<Country>()
            .Fetch(x => x.Translations).Eager
            .JoinAlias(q => q.Translations, () => countryLanguageValue, JoinType.LeftOuterJoin)
            .Where(() => countryLanguageValue.Culture == culture)
            .OrderBy(x => x.DisplayOrder).Asc
            .List();

        return results;

    }

    public Country GetCountryByIsoCode(string isoCode)
    {
        var result = UnitOfWork.CurrentSession.QueryOver<Country>()
            .Where(x => x.IsoCode == isoCode)
            .List()
            .FirstOrDefault();

        return result;
    }
于 2013-04-14T01:57:05.357 に答える
0

独自の計算プロパティをエンティティに追加して、Cityの子CountryからCountryIdなどを取得し、CityオブジェクトにCountryIdプロパティを設定できます。これは、マッパーがそのIdフィールドを実際のCountryエンティティに置き換えるためです。

public int CountryId { get { return this.Country.Id; } }

残念ながら、データベースのテーブルの一部(私には不要と思われるもの)に_プレフィックスを付けておくと、自動マッピングが面倒になると思いますが、他のテーブルにはありません。ウィキのこのガイドで説明されているように、テーブルが自動マッピングに非常に熟しているように見えることを排除できる場合:

https://github.com/jagregory/fluent-nhibernate/wiki/Auto-mapping

于 2013-03-30T02:02:07.797 に答える
0

ここで注意が必要なのは、エンティティCountryIdからアクセスできるようにしたいということだと思います。あなたはすでにあなたの国への言及を持っていて、あなたからCity単にそれをするので、私は正確に理由がわかりません。Country.IdCity

var countryID = myCityEntity.Country.Id;

ところで、特定の理由でこれが必要な場合は、マップする必要さえありません。単純なPOCOではなく、ドメインドライブの設計方法で考えて、エンティティにこれを行わせてください。

public int CountryId {
    get {
        return this.Country.Id;
    }
}
于 2013-04-01T21:43:27.933 に答える