如何将CultureInfo名称映射到SqlConnectionString的CurrentLanguage?

时间:2011-01-27 17:17:01

标签: .net sql-server-2008 c#-4.0 globalization cultureinfo

我试图根据应用程序的当前文化信息动态指定应用程序在运行时使用的SQL连接字符串的CurrentLanguage

我最初的尝试如下:

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());
    }
}

然而失败了,因为NameCultureInfo没有映射SQL服务器的sys.syslanguages中的名称。

有没有办法将其中一个CultureInfo名称属性映射到SQL服务器语言名称,或者我停止调用接受LCID的用户定义函数并将其映射到适当的名称以传递给SET LANGUAGE

3 个答案:

答案 0 :(得分:1)

在查看sys.syslanguages文档后,似乎有33种支持的语言。鉴于这么小的语言子集,我最终使用的最终解决方案是创建一个SqlConnectionLanguage类,工厂类使用该类根据当前文化的LCID动态指定SQL Server语言名称。

鉴于将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
}

答案 1 :(得分:0)

我认为CultureInfo具有LCID属性。这应该映射到sys.syslanguages表中的LCID列。因此,您应该使用此LCID查询sys.syslanguages表以从Name列获取值,然后将此字符串传递给ConnectionStringBuilder。例如:SELECT name FROM sys.syslanguages WHERE lcid = 1033将返回“us_english”。

我意识到你需要连接到DB才能这样做,因此需要一个连接字符串,所以我可能会在这里给出一个无用的答案。但是您可以在不指定CurrentLanguage的情况下查询语言。

答案 2 :(得分:0)

也许这很难看......但是你可以这样做:

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

此外,也许你可以使用像这里的Windows API函数 How to convert Microsoft Locale ID (LCID) into language code or Locale object in Java

然后可以玩它直到它适合你。无论哪种方式,祝你好运:)