Как сопоставить имя CultureInfo с CurrentLanguage объекта SqlConnectionString? - PullRequest
1 голос
/ 27 января 2011

Я пытаюсь динамически указать CurrentLanguage строк подключения SQL, используемых приложением во время выполнения, на основе текущей информации о культуре приложения.

Моя первоначальная попытка была следующей:

foreach (ConnectionStringSettings item in ConfigurationManager.ConnectionStrings)
{
    if (!this.ConnectionStrings.ContainsKey(item.Name))
    {
        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(item.ConnectionString);
        if (String.IsNullOrEmpty(builder.CurrentLanguage))
        {
            var culture = Thread.CurrentThread.CurrentUICulture ?? Thread.CurrentThread.CurrentCulture;
            builder.CurrentLanguage = culture.Name;
        }

        this.ConnectionStrings.Add(item.Name, builder.ToString());
    }
}

Однако это не удается, поскольку Имя из CultureInfo не отображает имя в sys.syslanguages ​​ изСервер SQL.

Есть ли способ сопоставить одно из свойств имени CultureInfo с именем языка сервера SQL, или я застрял, вызывая пользовательскую функцию, которая принимает LCID и сопоставляет это с соответствующим именем для передачи УСТАНОВИТЬ ЯЗЫК ?

Ответы [ 3 ]

1 голос
/ 02 февраля 2011

После просмотра документации sys.syslanguages ​​выясняется, что существует 33 поддерживаемых языка.Учитывая такое небольшое подмножество языков, окончательное решение, которое я использовал в итоге, заключалось в создании класса SqlConnectionLanguage, который используется классом фабрики для динамического указания имени языка SQL Server на основе LCID текущей культуры.* Учитывая сложность сопоставления CultureInfo с именем или псевдонимом языка SQL Server, создание вспомогательного класса, в котором инкапсулированы 33 поддерживаемых языка, представляется наиболее простым подходом.следующее:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(this.ConnectionStrings[name]);
if (String.IsNullOrEmpty(builder.CurrentLanguage))
{
    var culture = Thread.CurrentThread.CurrentUICulture ?? Thread.CurrentThread.CurrentCulture;

    if (culture != null)
    {
        var language = SqlConnectionLanguage.Create(culture);

        if (language != null)
        {
            builder.CurrentLanguage = language.Name;
        }
    }
}

return new SqlConnection(builder.ToString());

Реализация класса SqlConnectionLanguage:

/// <summary>
/// Represents a language supported by SQL Server.
/// </summary>
/// <remarks>
/// See <a href="http://msdn.microsoft.com/en-us/library/ms190303.aspx">sys.syslanguages (Transact-SQL)</a> 
/// for more information about culture support in SQL Server.
/// </remarks>
[Serializable()]
public class SqlConnectionLanguage : INotifyPropertyChanged, INotifyPropertyChanging
{
    //=======================================================================================================
    //  Constructors
    //=======================================================================================================
    #region SqlConnectionLanguage()
    /// <summary>
    /// Initializes a new instance of the <see cref="SqlConnectionLanguage"/> class.
    /// </summary>
    public SqlConnectionLanguage()
    {

    }
    #endregion

    #region SqlConnectionLanguage(int id, int localeId, string name, string alias)
    /// <summary>
    /// Initializes a new instance of the <see cref="SqlConnectionLanguage"/> class 
    /// using the specified unique identifier, locale identifier, name, and alias.
    /// </summary>
    /// <param name="id">The unique identifier for the language.</param>
    /// <param name="localeId">The  Microsoft Windows locale ID for the language.</param>
    /// <param name="name">The official name for the language.</param>
    /// <param name="alias">The alternative name for the language.</param>
    public SqlConnectionLanguage(int id, int localeId, string name, string alias) : this()
    {
        this.Id         = id;
        this.LocaleId   = localeId;
        this.Name       = name;
        this.Alias      = alias;
    }
    #endregion

    //=======================================================================================================
    //  Public Properties
    //=======================================================================================================
    #region Alias
    /// <summary>
    /// Gets or sets the alternative name for this language.
    /// </summary>
    /// <value>
    /// The alternative name for this language. 
    /// The default value is an <see cref="String.Empty"/> string.
    /// </value>
    public string Alias
    {
        get
        {
            return _languageAlias;
        }

        set
        {
            if (PropertyChangeNotifier.AreNotEqual(_languageAlias, value))
            {
                using (new PropertyChangeNotifier(OnPropertyChanging, OnPropertyChanged))
                {
                    _languageAlias = !String.IsNullOrEmpty(value) ? value : String.Empty;
                }
            }
        }
    }
    private string _languageAlias = String.Empty;
    #endregion

    #region Id
    /// <summary>
    /// Gets or sets the unique identifier for this language.
    /// </summary>
    /// <value>
    /// A <see cref="Int32"/> value that represents the  unique identifier for this language. 
    /// The default value is <i>zero</i>.
    /// </value>
    public int Id
    {
        get
        {
            return _languageId;
        }

        set
        {
            if (PropertyChangeNotifier.AreNotEqual(value, _languageId))
            {
                using (new PropertyChangeNotifier(OnPropertyChanging, OnPropertyChanged))
                {
                    _languageId = value;
                }
            }
        }
    }
    private int _languageId;
    #endregion

    #region InstalledLanguages
    /// <summary>
    /// Gets the installed languages for the SQL Server database engine.
    /// </summary>
    /// <value>
    /// A <see cref="ConcurrentDictionary{Int32, SqlConnectionLanguage}"/> collection that contains 
    /// the installed languages for the SQL Server database engine.
    /// </value>
    /// <remarks>
    /// The collection is keyed by the <see cref="SqlConnectionLanguage.Id"/> of the 
    /// contained <see cref="SqlConnectionLanguage"/> elements.
    /// </remarks>
    public static ConcurrentDictionary<int, SqlConnectionLanguage> InstalledLanguages
    {
        get
        {
            if (_languageInstalledLanguages == null)
            {
                _languageInstalledLanguages = new ConcurrentDictionary<int, SqlConnectionLanguage>();

                _languageInstalledLanguages.TryAdd(0, new SqlConnectionLanguage(0, 1033, "us_english", "English"));
                _languageInstalledLanguages.TryAdd(1, new SqlConnectionLanguage(1, 1031, "Deutsch", "German"));
                _languageInstalledLanguages.TryAdd(2, new SqlConnectionLanguage(2, 1036, "Français", "French"));
                _languageInstalledLanguages.TryAdd(3, new SqlConnectionLanguage(3, 1041, "日本語", "Japanese"));
                _languageInstalledLanguages.TryAdd(4, new SqlConnectionLanguage(4, 1030, "Dansk", "Danish"));
                _languageInstalledLanguages.TryAdd(5, new SqlConnectionLanguage(5, 3082, "Español", "Spanish"));
                _languageInstalledLanguages.TryAdd(6, new SqlConnectionLanguage(6, 1040, "Italiano", "Italian"));
                _languageInstalledLanguages.TryAdd(7, new SqlConnectionLanguage(7, 1043, "Nederlands", "Dutch"));
                _languageInstalledLanguages.TryAdd(8, new SqlConnectionLanguage(8, 2068, "Norsk", "Norwegian"));
                _languageInstalledLanguages.TryAdd(9, new SqlConnectionLanguage(9, 2070, "Português", "Portuguese"));
                _languageInstalledLanguages.TryAdd(10, new SqlConnectionLanguage(10, 1035, "Suomi", "Finnish"));
                _languageInstalledLanguages.TryAdd(11, new SqlConnectionLanguage(11, 1053, "Svenska", "Swedish"));
                _languageInstalledLanguages.TryAdd(12, new SqlConnectionLanguage(12, 1029, "čeština", "Czech"));
                _languageInstalledLanguages.TryAdd(13, new SqlConnectionLanguage(13, 1038, "magyar", "Hungarian"));
                _languageInstalledLanguages.TryAdd(14, new SqlConnectionLanguage(14, 1045, "polski", "Polish"));
                _languageInstalledLanguages.TryAdd(15, new SqlConnectionLanguage(15, 1048, "română", "Romanian"));
                _languageInstalledLanguages.TryAdd(16, new SqlConnectionLanguage(16, 1050, "hrvatski", "Croatian"));
                _languageInstalledLanguages.TryAdd(17, new SqlConnectionLanguage(17, 1051, "slovenčina", "Slovak"));
                _languageInstalledLanguages.TryAdd(18, new SqlConnectionLanguage(18, 1060, "slovenski", "Slovenian"));
                _languageInstalledLanguages.TryAdd(19, new SqlConnectionLanguage(19, 1032, "ελληνικά", "Greek"));
                _languageInstalledLanguages.TryAdd(20, new SqlConnectionLanguage(20, 1026, "български", "Bulgarian"));
                _languageInstalledLanguages.TryAdd(21, new SqlConnectionLanguage(21, 1049, "русский", "Russian"));
                _languageInstalledLanguages.TryAdd(22, new SqlConnectionLanguage(22, 1055, "Türkçe", "Turkish"));
                _languageInstalledLanguages.TryAdd(23, new SqlConnectionLanguage(23, 2057, "British", "British English"));
                _languageInstalledLanguages.TryAdd(24, new SqlConnectionLanguage(24, 1061, "eesti", "Estonian"));
                _languageInstalledLanguages.TryAdd(25, new SqlConnectionLanguage(25, 1062, "latviešu", "Latvian"));
                _languageInstalledLanguages.TryAdd(26, new SqlConnectionLanguage(26, 1063, "lietuvių", "Lithuanian"));
                _languageInstalledLanguages.TryAdd(27, new SqlConnectionLanguage(27, 1046, "Português (Brasil)", "Brazilian"));
                _languageInstalledLanguages.TryAdd(28, new SqlConnectionLanguage(28, 1028, "繁體中文", "Traditional Chinese"));
                _languageInstalledLanguages.TryAdd(29, new SqlConnectionLanguage(29, 1042, "한국어", "Korean"));
                _languageInstalledLanguages.TryAdd(30, new SqlConnectionLanguage(30, 2052, "简体中文", "Simplified Chinese"));
                _languageInstalledLanguages.TryAdd(31, new SqlConnectionLanguage(31, 1025, "Arabic", "Arabic"));
                _languageInstalledLanguages.TryAdd(32, new SqlConnectionLanguage(32, 1054, "ไทย", "Thai"));
            }
            return _languageInstalledLanguages;
        }
    }
    private static ConcurrentDictionary<int, SqlConnectionLanguage> _languageInstalledLanguages;
    #endregion

    #region LocaleId
    /// <summary>
    /// Gets or sets the Microsoft Windows locale ID for this language.
    /// </summary>
    /// <value>
    /// A <see cref="Int32"/> value that represents the Microsoft Windows locale ID for this language. 
    /// The default value is <i>zero</i>.
    /// </value>
    public int LocaleId
    {
        get
        {
            return _languageLocaleId;
        }

        set
        {
            if (PropertyChangeNotifier.AreNotEqual(value, _languageLocaleId))
            {
                using (new PropertyChangeNotifier(OnPropertyChanging, OnPropertyChanged))
                {
                    _languageLocaleId = value;
                }
            }
        }
    }
    private int _languageLocaleId;
    #endregion

    #region Name
    /// <summary>
    /// Gets or sets the official name for this language.
    /// </summary>
    /// <value>
    /// The official name for this language. 
    /// The default value is an <see cref="String.Empty"/> string.
    /// </value>
    public string Name
    {
        get
        {
            return _languageName;
        }

        set
        {
            if (PropertyChangeNotifier.AreNotEqual(_languageName, value))
            {
                using (new PropertyChangeNotifier(OnPropertyChanging, OnPropertyChanged))
                {
                    _languageName = !String.IsNullOrEmpty(value) ? value : String.Empty;
                }
            }
        }
    }
    private string _languageName = String.Empty;
    #endregion

    //=======================================================================================================
    //  Public Methods
    //=======================================================================================================
    #region Create(CultureInfo culture)
    /// <summary>
    /// Creates a new <see cref="SqlConnectionLanguage"/> using the specified <paramref name="culture"/>.
    /// </summary>
    /// <param name="culture">The <see cref="CultureInfo"/> to create</param>
    /// <returns>
    /// A new <see cref="SqlConnectionLanguage"/> using the specified <paramref name="culture"/>. 
    /// If no SQL Server language exists for the specified <paramref name="culture"/>, 
    /// returns a <see langword="null"/> reference (Nothing in Visual Basic).
    /// </returns>
    /// <exception cref="ArgumentNullException">The <paramref name="culture"/> is a <see langword="null"/> reference (Nothing in Visual Basic).</exception>
    public static SqlConnectionLanguage Create(CultureInfo culture)
    {
        Guard.AgainstNullReference(culture, "culture");

        return InstalledLanguages.Values.FirstOrDefault(language => language.LocaleId == culture.LCID);
    }
    #endregion

    #region ToString()
    /// <summary>
    /// Returns a string that represents the current <see cref="SqlConnectionLanguage"/>.
    /// </summary>
    /// <returns>
    /// A string that represents the current <see cref="SqlConnectionLanguage"/>.
    /// </returns>
    public override string ToString()
    {
        return this.Alias;
    }
    #endregion

    //=======================================================================================================
    //  INotifyPropertyChanged Implementation
    //=======================================================================================================
    #region PropertyChanged
    /// <summary>
    /// Occurs when a property value changes.
    /// </summary>
    /// <remarks>
    /// The <see cref="PropertyChanged"/> event can indicate all properties on the object have changed 
    /// by using either a <b>null</b> reference (Nothing in Visual Basic) or <see cref="String.Empty"/> 
    /// as the property name in the <see cref="PropertyChangedEventArgs"/>.
    /// </remarks>
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion

    #region OnPropertyChanged(string propertyName)
    /// <summary>
    /// Raises the <see cref="PropertyChanged"/> event.
    /// </summary>
    /// <param name="propertyName">The name of the property that changed.</param>
    protected void OnPropertyChanged(string propertyName)
    {
        this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }
    #endregion

    #region OnPropertyChanged(PropertyChangedEventArgs e)
    /// <summary>
    /// Raises the <see cref="PropertyChanged"/> event.
    /// </summary>
    /// <param name="e">A <see cref="PropertyChangedEventArgs"/> that contains the event data.</param>
    protected void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;

        if (handler != null)
        {
            handler(this, e);
        }
    }
    #endregion

    //=======================================================================================================
    //  INotifyPropertyChanging Implementation
    //=======================================================================================================
    #region PropertyChanging
    /// <summary>
    /// Occurs when a property value is changing.
    /// </summary>
    /// <remarks>
    /// The <see cref="PropertyChanging"/> event can indicate all properties on the object are changing 
    /// by using either a <b>null</b> reference (Nothing in Visual Basic) or <see cref="String.Empty"/> 
    /// as the property name in the <see cref="PropertyChangingEventArgs"/>.
    /// </remarks>
    public event PropertyChangingEventHandler PropertyChanging;
    #endregion

    #region OnPropertyChanging(string propertyName)
    /// <summary>
    /// Raises the <see cref="PropertyChanging"/> event.
    /// </summary>
    /// <param name="propertyName">The name of the property that is changing.</param>
    protected void OnPropertyChanging(string propertyName)
    {
        this.OnPropertyChanging(new PropertyChangingEventArgs(propertyName));
    }
    #endregion

    #region OnPropertyChanging(PropertyChangingEventArgs e)
    /// <summary>
    /// Raises the <see cref="PropertyChanging"/> event.
    /// </summary>
    /// <param name="e">A <see cref="PropertyChangingEventArgs"/> that contains the event data.</param>
    protected void OnPropertyChanging(PropertyChangingEventArgs e)
    {
        PropertyChangingEventHandler handler = this.PropertyChanging;

        if (handler != null)
        {
            handler(this, e);
        }
    }
    #endregion
}
0 голосов
/ 01 февраля 2011

Может быть, это очень уродливо ... но вы могли бы что-то вроде этого:

 builder.CurrentLanguage = culture.EnglishName.Substring(0, culture.EnglishName.IndexOf(" "))

Также, возможно, вы могли бы использовать функцию Windows API, как здесь Как конвертировать Microsoft LocaleID (LCID) в код языка или объект Locale в Java

, а затем, возможно, поэкспериментируйте с ним, пока он не подойдет вам.В любом случае, удачи:)

0 голосов
/ 28 января 2011

Я думаю, что CultureInfo имеет свойство LCID.Это должно соответствовать столбцу LCID в таблице sys.syslanguages.Поэтому вам, вероятно, следует запросить таблицу sys.syslanguages ​​с этим LCID, чтобы получить значение из столбца Name, а затем передать эту строку в ConnectionStringBuilder.Например: SELECT name FROM sys.syslanguages WHERE lcid = 1033 вернет "us_english".

Я понимаю, что для этого вам нужно соединение с БД и, следовательно, строка соединения, поэтому я мог бы дать здесь бесполезный ответ.Но вы можете запрашивать языки без указания CurrentLanguage.

...