我不断遇到 i18n 要求,我的数据(不是我的 UI)需要国际化。
public class FooEntity
{
public long Id { get; set; }
public string Code { get; set; } // Some values might not need i18n
public string Name { get; set } // but e.g. this needs internationalized
public string Description { get; set; } // and this too
}
我可以使用哪些方法?
我尝试过的一些事情:-
1)在数据库中存储资源键
public class FooEntity
{
...
public string NameKey { get; set; }
public string DescriptionKey { get; set; }
}
- 优点:不需要复杂的查询来获得翻译的实体。
System.Globalization
为您处理后备。 - 缺点:管理员用户无法轻松管理翻译(必须在我
Foo
更改时部署资源文件)。
2)使用LocalizableString
实体类型
public class FooEntity
{
...
public int NameId { get; set; }
public virtual LocalizableString Name { get; set; }
public int NameId { get; set; }
public virtual LocalizableString Description { get; set; }
}
public class LocalizableString
{
public int Id { get; set; }
public ICollection<LocalizedString> LocalizedStrings { get; set; }
}
public class LocalizedString
{
public int Id { get; set; }
public int ParentId { get; set; }
public virtual LocalizableString Parent { get; set; }
public int LanguageId { get; set; }
public virtual Language Language { get; set; }
public string Value { get; set; }
}
public class Language
{
public int Id { get; set; }
public string Name { get; set; }
public string CultureCode { get; set; }
}
- 优点:同一个表中的所有本地化字符串。可以按字符串执行验证。
- 缺点:查询很可怕。必须为父实体上的每个可本地化字符串包含一次 LocalizedStrings 表。后备是困难的,涉及广泛的加入。在检索例如表的数据时,还没有找到避免 N+1 的方法。
3) 使用具有所有不变属性的父实体和包含所有本地化属性的子实体
public class FooEntity
{
...
public ICollection<FooTranslation> Translations { get; set; }
}
public class FooTranslation
{
public long Id { get; set; }
public int ParentId { get; set; }
public virtual FooEntity Parent { get; set; }
public int LanguageId { get; set; }
public virtual Language Language { get; set; }
public string Name { get; set }
public string Description { get; set; }
}
public class Language
{
public int Id { get; set; }
public string Name { get; set; }
public string CultureCode { get; set; }
}
- 优点:没有那么难(但仍然太难了!)将实体完整翻译到内存中。
- 缺点:实体数量翻倍。无法处理实体的部分翻译 - 尤其是在 Name 来自
es
但 Description 来自的情况下es-AR
。
我对解决方案有三个要求
用户可以在运行时编辑实体、语言和翻译
用户可以根据 System.Globalization 提供来自回退的缺失字符串的部分翻译
实体可以被带入内存而不会遇到例如 N+1 问题