Во-первых, будьте очень осведомлены об ограничениях. Для созданного пользователем контента вы смотрите на перевод сообщества (неустойчивый), машинный перевод (ненадежный) или платные переводчики (дорогие!), Если вы хотите локализовать материал, который ваши пользователи входят в ваше приложение. Вы можете попросить своих пользователей предоставить две версии - одну для вашей культуры по умолчанию (на английском языке) и одну для их локализованной культуры, чтобы вы могли предоставить перевод для других пользователей?
Во-вторых, будьте готовы к некоторым чрезвычайно длинным перемещениям базы данных ... если у вас есть четыре столбца текста в электронной таблице Excel, вдруг вы имеете дело с введением каждого значения в вашу систему перевода, извлечение локализованного идентификатора, а затем сохраните , что в таблице, которую вы фактически импортируете, и SELECT *
предоставит вам только идентификаторы фраз, которые вам нужно разрешить обратно в строки, локализуя их против ваших таблиц перевода.
Это говорит о том, что вы можете локализовать множество таблиц поиска, раскрывающихся списков и т. Д., Которые управляются базой данных в типичном проекте. В других комментариях уже упоминалось сохранение значений StringId в базе данных, относящихся к файлам или файлам внешних ресурсов, но если вы заинтересованы в том, чтобы сохранить весь свой локализованный текст в базе данных вместе с самими данными, вы можете найти этот подход полезным.
Мы использовали таблицу под названием «Фраза», которая содержит идентификатор и стандартный (английский) контент для каждого фрагмента текста в приложении.
другие ваши таблицы в конечном итоге выглядит так:
CREATE TABLE ProductType (
Id int primary key,
NamePhraseId int, -- link to the Phrase containing the name of this product type.
DescriptionPhraseId int
)
Создайте вторую таблицу культуры, которая содержит конкретные и нейтральные культуры вы поддерживаете. Для бонусных точек используйте эту таблицу как самореферентное дерево (каждая запись культуры содержит нулевую ссылку на ParentCultureCode), поэтому вы можете отступить от определенных культур («fr-CA» для канадских французов) до нейтральных культур («fr», если ни одна из региональных локализации не существует), к вашей инвариантной/культуре по умолчанию (обычно «ан», потому что он так широко распространен)
ваших фактические переводов в таблице LocalizedPhrase, что выглядит следующим образом:
CREATE TABLE LocalizedPhrase (
PhraseId int primary key,
CultureCode varchar(8) primary key,
Content nvarchar(255) -- the actual localized content
)
Вы можете распространите эту модель, если вы хотите обеспечить локальную/женскую специфику:
CREATE TABLE GenderedLocalizedPhrase (
PhraseId int primary key,
CultureCode varchar(8) primary key,
GenderCode char(1) primary key, -- 'm', 'f' or '?' - links to Gender table
Content nvarchar(255)
)
Вы захотите кэшировать весь этот табличный график в памяти и соответствующим образом изменить свои стратегии запроса/объединения - кэширование локализаций внутри классов фраз и переопределение метода ToString() для объекта Phrase для проверки текущей культуры потоков - это один из подходов. Если вы попытаетесь сделать этот материал в ваших запросах, вы будете нести существенные расходы производительности и каждый запрос будет в конечном итоге выглядит так:
-- assume @MyCulture contains the culture code ('ca-FR') that we are looking for:
SELECT
Product.Id,
Product.Name,
COALESCE(ProductStatusLocalizedPhrase.Content, ProductStatusPhrase.Content) as ProductStatus,
COALESCE(ProductTypeLocalizedPhrase.Content, ProductTypePhrase.Content) as ProductType,
FROM Product
INNER JOIN ProductStatus ON Product.StatusId = ProductStatus.Id
INNER JOIN Phrase as ProductStatusPhrase ON ProductStatus.NamePhraseId = Phrase.Id
LEFT JOIN LocalizedPhrase as ProductStatusLocalizedPhrase
ON ProductStatus.NamePhraseId = ProductStatusLocalizedPhrase.Id and CultureCode = @MyCulture
INNER JOIN ProductType ON Product.TypeId = ProductType.Id
INNER JOIN Phrase as ProductTypePhrase ON ProductType.NamePhraseId = Phrase.Id
LEFT JOIN LocalizedPhrase as ProductTypeLocalizedPhrase
ON ProductType.NamePhraseId = ProductTypeLocalizedPhrase.Id and CultureCode = @MyCulture