Я постоянно сталкиваюсь с требованием i18n, когда мои данные (а не мой пользовательский интерфейс) должны быть интернационализированы.Интернационализация содержимого в платформе Entity Framework
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; }
}
- Pros: Все локализованные строки в одной таблице. Проверка может выполняться в строке.
- Против: запросы ужасные. Обязательно. Включите таблицу 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; }
}
- Плюсы: Не так трудно (но все еще слишком сильно), чтобы получить! полный перевод сущности в память.
- Против: удвоить количество сущностей. Невозможно обрабатывать частичные переводы объекта - особенно в том случае, когда, скажем, имя исходит от
es
, но описание исходит отes-AR
.
У меня есть три требования для решения
Пользователей могут редактировать сущности, язык и переводы во время выполнения
Пользователей могут поставлять частичные переводы недостающих строк, поступающих из запасного варианта в соответствии с Системой. Глобализация
Объекты могут быть внесены в память без запуска например, N + 1 выпусков
Еще не ответил, меня тоже интересовало. – polkduran
Непонятно, что вы считаете приемлемым ответом. Если у кого-то есть вариант 4, у него наверняка будут плюсы и минусы. – explunit
Уточненный вопрос. Я не ожидаю, что там будет идеальное решение, но, надеюсь, есть один лучше, чем я придумал. –