En primer lugar, tenga en cuenta las limitaciones. Para el contenido creado por el usuario, está buscando la traducción de la comunidad (errática), la traducción automática (no confiable) o el pago de traductores humanos (¡caros!) Si desea localizar las cosas que los usuarios ingresan en su aplicación. Es posible que desee solicitar a sus usuarios que proporcionen dos versiones, una para su cultura predeterminada (¿inglés?) Y otra para su cultura localizada, para que pueda proporcionar una traducción alternativa para otros usuarios.
En segundo lugar, prepárese para migraciones de bases de datos extremadamente largas ... si tiene cuatro columnas de texto en una hoja de cálculo de Excel, de repente se trata de insertar cada valor en su sistema de traducción, recuperar la ID localizada, y luego almacenar que en la tabla que está realmente importando, y SELECT *
solo le dará identificadores de frase, que debe resolver de nuevo en cadenas localizándolos en sus tablas de traducción.
Dicho esto: puede localizar muchas de las tablas de búsqueda, listas desplegables, etc. que maneja la base de datos en un proyecto típico. Otros comentarios ya han mencionado el almacenamiento de valores de StringId en la base de datos que hacen referencia a archivos de recursos externos u hojas de cálculo, pero si está interesado en mantener TODO su texto localizado en la base de datos junto con los datos, tal vez le resulte útil este enfoque.
Hemos utilizado una tabla llamada Frase, que contiene la ID y el contenido predeterminado (en inglés) para cada texto de la aplicación.
Sus otras mesas terminan pareciéndose a esto:
CREATE TABLE ProductType (
Id int primary key,
NamePhraseId int, -- link to the Phrase containing the name of this product type.
DescriptionPhraseId int
)
crear una segunda tabla de Cultura, que contiene las culturas específicas y neutrales que estés de apoyo. Para obtener puntos de bonificación, implemente esta tabla como un árbol autorreferencial (cada registro de Cultura contiene una referencia de NullCripCultureCode), de modo que puede retroceder de culturas específicas ("fr-CA" para el francés canadiense) a culturas neutrales ("fr" si no existe una localización regional), a su referencia cultural de todos/defecto (normalmente, 'es' porque es tan ampliamente hablado)
sus traducciones reales están en una mesa LocalizedPhrase, que se parece a:
CREATE TABLE LocalizedPhrase (
PhraseId int primary key,
CultureCode varchar(8) primary key,
Content nvarchar(255) -- the actual localized content
)
puede extienda este modelo si desea proporcionar localizaciones específicas para hombres/mujeres:
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)
)
Querrá guardar en caché todo el gráfico de la tabla en memoria y modificar sus estrategias de consulta/unión en consecuencia: almacenar en memoria caché las localizaciones dentro de las clases de Frases y reemplazar el método ToString() en el objeto Frase para inspeccionar la cultura del hilo actual. Si tratas de hacer estas cosas dentro de sus consultas, se incurrirá en un costo sustancial el rendimiento y cada consulta va a terminar con este aspecto:
-- 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