Наконец, я создал свои собственные классы для поддержки многоязычия в моих данных базы данных.
Я испанский, и я перевел свой код для поста здесь. Возможно, в нем есть простые синтаксические ошибки,
- У вас есть класс Product, у которого свойство ProductName имеет тип MultilingualString
- Класс MultilingualString имеет текст по умолчанию для каждого неизвестного языка и имеет список переводов этого текста. У него есть методы для установки различных переводов (SetTranslation) и методы для перевода на определенный язык. К концу этого класса есть свойство tu переводить в текущий поток культуры (перевод)
- У вас есть класс Translation, в котором есть язык и переведенный текст
Вот код:
public class Product
{
public int Id { get; set; }
public MultilingualString ProductName { get; set; }
}
public class MultilingualString
{
// You need it only to make the class persistent
public int Id { get; set; }
public string Text { get; set; }
public virtual ICollection<Translation> Translations { get; set; }
public string Translation { get { return Translate(); } }
public void SetTranslation(string language, string text)
{
if (Translations == null)
Translations = new List<Translation>();
var found = Translations.Where(t => t.Language.ToUpper() == language.ToUpper()).FirstOrDefault();
if (found == null)
Translations.Add(new Translation() { Language = language, Text = text });
else
found.Text = text;
}
public string Translate(string cultureName)
{
return Translate(new CultureInfo(cultureName));
}
public string Translate(CultureInfo culture = null)
{
if (culture == null)
culture = Thread.CurrentThread.CurrentCulture;
var translation = Translations == null
? null
: Translations.Where(
t =>
culture.Name.ToUpper(CultureInfo.InvariantCulture).StartsWith(
t.Language.ToUpper(CultureInfo.InvariantCulture))).FirstOrDefault();
return translation == null ? Text : translation.Text;
}
}
public class Translation
{
// You need it only to make the class persistent
public int Id { get; set; }
public string Language { get; set; }
public string Text { get; set; }
}
Вы можете создать класс DbContext и выполнить такой тест:
public class MultilingualContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
[TestClass]
public class Tests
{
[TestMethod]
public void ThisWorksFine()
{
using (var context = new MultilingualContext())
{
var product = new Product();
context.Products.Add(product);
product.ProductName = new MultilingualString() { Text = "Beer (default language)" };
product.ProductName.SetTranslation("en", "Beer");
product.ProductName.SetTranslation("es", "Cerveza");
product.ProductName.SetTranslation("fr", "Bière");
product.ProductName.SetTranslation("de", "Bier");
var spanishProductName = product.ProductName.Translate(new CultureInfo("es"));
Assert.AreEqual(spanishProductName, "Cerveza");
var culture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("en");
Assert.AreEqual(product.ProductName.Translation, "Beer");
Thread.CurrentThread.CurrentCulture = new CultureInfo("es");
Assert.AreEqual(product.ProductName.Translation, "Cerveza");
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr");
Assert.AreEqual(product.ProductName.Translation, "Bière");
Thread.CurrentThread.CurrentCulture = new CultureInfo("de");
Assert.AreEqual(product.ProductName.Translation, "Bier");
Thread.CurrentThread.CurrentCulture = new CultureInfo("it");
Assert.AreEqual(product.ProductName.Translation, "Beer (default language)");
Thread.CurrentThread.CurrentCulture = culture;
context.SaveChanges();
}
}
}
Я просто хочу покончить с этим, надеюсь, это нормально работает;)
С наилучшими пожеланиями!
UPDATE
Еще одна вещь, при удалении продукта не удаляйте многоязычную строковую запись. Вы можете добавить бизнес логический к вашим услугам и удалить многоязычную запись при удалении продукта.
Или нет! если вы не удалите многоязычную запись, у вас будет все больше и больше записей MultilingualStrings, и вы можете воспользоваться этим репозиторием, чтобы предлагать переведенные названия продуктов для будущих продуктов.
Вы можете добавить набор MultilingualStrings в контекст:
public class MultilingualContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<MultilingualString> MultilingualStrings { get; set; }
}
Затем вы можете искать MultilingualStrings в событии ProductNameTextBoxOnChange, например:
context.MultilingualStrings.Where(s => s.Translation.StartsWith(ProductNameTextBox.Text));
И вы можете использовать этот репозиторий для других свойств других объектов, которые имеют многоязычные строки.