Если ваш экземпляр sqlite был скомпилирован с включенным расширением JSON1 , это легко:
SELECT * FROM yourtable AS t
WHERE EXISTS (SELECT j.id FROM json_each(t.i18n) AS j
WHERE json_extract(j.value, '$.name') LIKE 'NAME_IN%');
Однако, небольшое изменение вашей второй идеи, вытаскивая все эти JSON -объекты в строках таблицы (вместо одного столбца на язык, который быстро становится громоздким по мере роста количества языков), вероятно, является лучшим вариантом:
CREATE TABLE translations(original TEXT, language TEXT, translated TEXT
, PRIMARY KEY(original, language)) WITHOUT ROWID;
INSERT INTO translations VALUES ('name', 'ru', 'название');
-- etc.
Масштабируемый, легче проверять и обновлять данные, позволяющие получить только соответствующие биты, работать лучше и т. д.
Я использую Расширение локализации WPF . Это действительно простой способ локализовать любой тип DependencyProperty
на DependencyObject
s.
Text = {LocText ResAssembly: ResFile: ResKey}
INotifyPropertyChanged
для расширенного использования Выполните следующие действия:
1) Поместите все фрагменты String
в отдельный файл ресурсов.
Пример: StringResources.xaml
:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<!-- String resource that can be localized -->
<system:String x:Key="All_Vehicles">All Vehicles</system:String>
</ResourceDictionary>
2) Сделайте копии для каждого языка и добавьте их (переведенные) в объединенные словари. Не забудьте добавить код ISO страны, чтобы упростить процесс.
Пример App.xaml
:
<Application x:Class="WpfStringTables.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="StringResources.de-DE.xaml" />
<ResourceDictionary Source="StringResources.nl-NL.xaml" />
<ResourceDictionary Source="StringResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Последний файл ресурсов со строками будет использоваться для замены текстовых частей в коде.
3a) Использовать части текста из таблицы String
:
Пример Window1.xaml
:
<Window x:Class="WpfStringTables.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Button Margin="51,82,108,129" Name="AllVehiclesButton"
Content="{StaticResource All_Vehicles}"/>
</Grid>
</Window>
3b) Загрузить ресурс из кода (только используйте этот код, если вы не хотите устанавливать через XAML
):
void PageLoad()
{
string str = FindResource("All_Vehicles").ToString();
}
4) Переключиться на новую культуру при запуске приложения:
Codesnippet from App.xaml. CS
:
public static void SelectCulture(string culture)
{
if (String.IsNullOrEmpty(culture))
return;
//Copy all MergedDictionarys into a auxiliar list.
var dictionaryList = Application.Current.Resources.MergedDictionaries.ToList();
//Search for the specified culture.
string requestedCulture = string.Format("StringResources.{0}.xaml", culture);
var resourceDictionary = dictionaryList.
FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
if (resourceDictionary == null)
{
//If not found, select our default language.
requestedCulture = "StringResources.xaml";
resourceDictionary = dictionaryList.
FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
}
//If we have the requested resource, remove it from the list and place at the end.
//Then this language will be our string table to use.
if (resourceDictionary != null)
{
Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
}
//Inform the threads of the new culture.
Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
}
Джош Смит написал подробное руководство о своем предпочтительном методе для этого: Создание интернационализированного мастера в WPF .
Это может указать вам на большую редизайн ( это решение MVVM ), но использование MVVM, похоже, того стоит и по другим причинам.