【问题标题】:ASP.NET MVC5 Generic Translation method for database entities用于数据库实体的 ASP.NET MVC5 通用翻译方法
【发布时间】:2014-03-14 21:18:18
【问题描述】:

对于一个数据库实体,我有两种方法可以获取所选语言的翻译(如果有的话),或者默认语言翻译。

public string GetName(int? LanguageId, int? DefaultLanguageId)
{
    string retval = "";
    var textInSelectedLanguage = this.CategoryTexts.Where(w => w.LanguageId == LanguageId).SingleOrDefault();
    if (textInSelectedLanguage == null)
    {
        retval = this.CategoryTexts.Where(w => w.LanguageId == DefaultLanguageId).SingleOrDefault().Name;
    }
    else
    {
        retval = textInSelectedLanguage.Name;
    }
    return retval;
}

public string GetDescription(int? LanguageId, int? DefaultLanguageId)
{
    string retval = "";
    var textInSelectedLanguage = this.CategoryTexts.Where(w => w.LanguageId == LanguageId).SingleOrDefault();
    if (textInSelectedLanguage == null)
    {
        retval = this.CategoryTexts.Where(w => w.LanguageId == DefaultLanguageId).SingleOrDefault().Description;
    }
    else
    {
        retval = textInSelectedLanguage.Description;
    }
    return retval;
}

如您所见,它们非常相似。如果我有更多要翻译的属性,这将不是一个好的实现。其他翻译的行为类似。

如何将这段代码简化为一种方法?

我尝试使用反射,但没有任何结果。

稍后...

我将我的代码简化为一种方法,该方法返回一个实体实例,其中包含所选语言或默认语言的所有属性:

public CategoryText GetTranslation(int? DesiredLanguageId, int? DefaultLanguageId)
{
    CategoryText retval = null;
    var textInSelectedLanguage = this.CategoryTexts.Where(w => w.LanguageId == DesiredLanguageId).SingleOrDefault();
    if (textInSelectedLanguage == null)
    {
        retval = this.CategoryTexts.Where(w => w.LanguageId == DefaultLanguageId).SingleOrDefault();
    }
    else
    {
        retval = textInSelectedLanguage;
    }
    return retval;
}

我认为通过尝试找到一种方法来将我的CategoryTexts Dbset 替换为任何其他 DbSet 数据库实体,可以轻松地使这种方法变得通用。我该怎么做?

【问题讨论】:

  • 您还想操作哪些其他数据库实体?他们是否有一个公共的基类或接口,上面有LanguageId 属性?

标签: asp.net-mvc generics asp.net-mvc-5


【解决方案1】:

假设您有一个合适的基类,您可以编写它:-

public T GetTranslation<T>(DbSet<T> set, int? DesiredLanguageId, int? DefaultLanguageId)
    where T:SomeBaseClassThatHasPropertyLanguageId
{
    return 
       set.SingleOrDefault(w => w.LanguageId == DesiredLanguageId) ??
       set.SingleOrDefault(w => w.LanguageId == DefaultLanguageId);
}

【讨论】:

  • 我也用另一种方式解决了这个问题。请看一下并告诉我您的意见。
【解决方案2】:

我以某种方式解决了这个问题。

我有一个使用以下方法的国际化类:

public static T GetDbEntityTranslation<T>(ITranslatable Entity)
{
    return (T)Entity.GetTranslation<T>(GetDefaultLanguage().Id, GetChosenLanguage().Id);
}

ITranslatable 接口:

public interface ITranslatable
{
    T GetTranslation<T>(int? DesiredLanguageId, int? DefaultLanguageId);
}

我的分类类:

public partial class Category : ITranslatable
{
    private LSEntities db = new LSEntities();

    public T GetTranslation<T>(int? DesiredLanguageId, int? DefaultLanguageId)
    {
        CategoryText retval = null;
        retval = db.CategoryTexts.Where(w => w.LanguageId == DesiredLanguageId && w.CategoryId == this.Id).SingleOrDefault()
            ?? this.CategoryTexts.Where(w => w.LanguageId == DefaultLanguageId && w.CategoryId == this.Id).SingleOrDefault()
            ?? this.CategoryTexts.Where(w => w.CategoryId == this.Id).FirstOrDefault();
        if (retval == null)
            throw new Exception("No translation found for this object");
        return (T)(object)retval;
    }
}

问题是我需要根据存储在Category 类中的类别ID 获取我的翻译。我的翻译在CategoryTexts 属性中搜索。

【讨论】:

  • 如果你的继承关系正确,你应该能够在没有任何转换的情况下做到这一点。 (T)(object) 很讨厌。但我建议您在 programmers.stackexchange.com 上讨论编码风格,因为那是更合适的代码审查问题场所。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-03
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多