4

CodeFirst で MVC を使用して多言語 Web サイトを作成しています。このチュートリアル ( http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating -an-entity-framework-data-model-for-an-asp-net-mvc-application ) しかし、いくつかの問題に直面しています…</p>

詳しく説明してみますので、長文で申し訳ありません…</p>

name 属性をローカライズする必要がある次の属性 (Date、Name) を持つエンティティ T があるとします。エンティティとそのローカライズされたバージョンを表すために、次のエンティティを作成しました。

public class T
{
    #region Primitive Properties

    public int TID { get; set; }

    [DisplayFormat(DataFormatString = "{0:d}")]
    [Required]
    public DateTime DateCreated { get; set; }

    #endregion

    #region Localized Properties

    protected T_Locale TWithCurrentLocaleOrCreate
    {
        get
        {
            T_Locale t = this.T_Locales.SingleOrDefault(record => record.LocaleID == Locale.CurrentLocale.LocaleID);
            // If the object is not available with the current locale,
            // create it
            if (t == null)
            {
                t = new T_Locale
                {
                    Locale = Locale.CurrentLocale
                };

                this.T_Locales.Add(t);
            }

            return t;
        }
    }

    protected T_Locale TWithCurrentLocaleOrDefault
    {
        get
        {
            T_Locale t = this.T_Locales.SingleOrDefault(record => record.LocaleID == Locale.CurrentLocale.LocaleID);
            // If the object is not available with the current locale,
            // return it with the default locale
            if (t == null)
            {
                t = this.T_Locales.SingleOrDefault(record => record.LocaleID == Locale.DefaultLocale.LocaleID);
                // If the object is not available with the current locale,
                // return it with any available locale
                if (t == null)
                    t = this.T_Locales.First();
            }

            return t;
        }
    }

    [NotMapped]
    public string Name
    {
        get
        {
            return this.TWithCurrentLocaleOrDefault.Name;
        }
        set
        {
            this.TWithCurrentLocaleOrCreate.Name = value;
        }
    }

    #endregion

    #region Navigation Properties

    public virtual ICollection<T_Locale> T_Locales { get; set; }

    #endregion
}


public class T_Locale
{
    #region Primitive Properties

    [Key]
    [Column(Order = 0)]
    public int TID { get; set; }

    [Key]
    [Column(Order = 1)]
    public int LocaleID { get; set; }

    [Required]
    public string Name { get; set; }

    #endregion

    #region Navigation Properties

    public virtual T T { get; set; }

    public virtual Locale Locale { get; set; }

    #endregion
}


public class Locale
{
    #region Primitive Properties

    public int LocaleID { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string DisplayName { get; set; }

    #endregion

    #region Navigation Properties

    public virtual ICollection<T_Locale> T_Locales { get; set; }

    #endregion

    #region Current Locale Properties

    protected static string DefaultLocaleName
    {
        get
        {
            return "en";
        }
    }

    private static Locale _DefaultLocale;
    public static Locale DefaultLocale
    {
        get
        {
            DatabaseContext database = new DatabaseContext();
            _DefaultLocale = database.Locales.SingleOrDefault(record => record.Name == Locale.DefaultLocaleName);

            return _DefaultLocale;
        }
    }

    private static Locale _CurrentLocale;
    public static Locale CurrentLocale
    {
        get
        {
            DatabaseContext database = new DatabaseContext();

            if (_CurrentLocale == null)
            {
                // To Avoid the large logic behind for getting the current locale I’m using the default one here…
                _CurrentLocale = Locale.DefaultLocale;
            }

            return _CurrentLocale;
        }
    }

    #endregion
}

ここで、T: は関心のあるエンティティであり、T_Locale はローカライズする必要があるプロパティのみを含む T のローカライズ バージョンです。お気づきかもしれませんが、T (名前) に NotMapped 属性を記述してプロパティの現在のローカライズされたバージョン Name… このプロパティは、現在のロケールの名前を返す必要があり、setter を呼び出すときに、現在のロケールの名前の値を変更する必要があります。

Razor ビューを使用して、それ以上変更せずに T のコントローラーを作成しました。作成ビューに移動すると、正しいビューが表示されますが、作成ボタンをクリックすると、メソッド「TWithCurrentLocaleOrDefault」から例外が発生します。セッターを呼び出す前に Name プロパティのゲッターから呼び出されていることに気付きました...作成したばかりの T インスタンスのローカライズされたバージョンがないため、メソッドから例外が発生しています。

ここに何かが欠けているのか、それとも間違ったロジックを使用しているのかわかりません。何が問題なのかを説明するか、Mvc を使用してローカリゼーションを処理するための優れたチュートリアルまたはサンプル コードを教えてください。

アップデート:

問題は、複数の Context インスタンスを作成していることでした。そのため、適切なロジックがあれば、ローカライズされたエンティティ (T の現在の T_Locale) の現在ローカライズされているインスタンスにアクセスする際に使用しているロジックを変更する必要があると思います。そのような場合は、私を指摘してください...

非常に長い質問で申し訳ありませんが、どんな助けでも大歓迎です。

4

1 に答える 1