1、简介
开发的系统中,有些页面上的文字不同的用户可能想显示的内容不同,还有用户添加的菜单需要多语言支持,微软提供的resource文件不能很好地解决(用户没法根据自己的需要修改文字),所以采用基于数据库的多语言。
2、设计思路
1、数据表结构
语言表
1: CREATE TABLE [dbo].[T_LANGUAGE](2: [VALUE] [varchar](50) NOT NULL,3: [NAME] [varchar](50) NOT NULL,4: [STATUS] [varchar](10) NOT NULL5: ) ON [PRIMARY]6:7: GO8:9: ALTER TABLE [dbo].[T_LANGUAGE] ADD CONSTRAINT [DF_T_LANGUAGE_Status] DEFAULT ((1)) FOR [STATUS]10: GO11:键值对表12: CREATE TABLE [dbo].[T_KEY_VALUE](13: [KEY] [varchar](50) NOT NULL,14: [LANGUAGE_VALUE] [varchar](50) NOT NULL,15: [SYSTEM_NAME] [varchar](50) NOT NULL,16: [VALUE] [varchar](500) NULL17: ) ON [PRIMARY]2、工作方式
在程序加载时,把数据库中的多语言键值对同时加载到内存中,用一个字典存储。当需要用到键值对时,直接从字典中获取。
如果键值对发生改变,则重新加载数据库中的所有键值对。
3、核心部分代码
1: using System;2: using System.Collections.Generic;3: using System.Linq;4: using System.Text;5: using System.Data;6: using System.Web;7: using FluentData;8: namespace SureSoft.Utility9: {10: public class LangInstance11: {12: static LangInstance()13: {14: LangInstance.Conifg = new LanguageConfig();15: }16: public static LanguageConfig Conifg { get; set; }17: private static Language _Lang;18: public static Language Lang { get { return _Lang; } }19: public static void Start()20: {21: if (string.IsNullOrWhiteSpace(LangInstance.Conifg.SystemName))22: {23: throw new Exception("系统名称不能为空");24: }25: string systemName = LangInstance.Conifg.SystemName;26: LangInstance.Conifg = ConfigManage.LanguageConfig;27: LangInstance.Conifg.SystemName = systemName;28: if (LangInstance.Conifg.GetLanguage == null)29: {30: LangInstance.Conifg.GetLanguage = () =>31: {32: if (HttpContext.Current.Session["Language"] == null || string.IsNullOrEmpty(HttpContext.Current.Session["Language"].ToString()))33: {34: return HttpContext.Current.Request.UserLanguages[0];35: }36: else37: {38: return HttpContext.Current.Session["Language"].ToString();39: }40: };41: }42: _Lang = new Language(LangInstance.Conifg);43: }44: public static void ReStart()45: {46: Start();47: }48: public static void Start(LanguageConfig config)49: {50: LangInstance.Conifg = config;51: Start();52: }53: }54: public class LanguageNameValuePair55: {56: public string Name { get; set; }57: public string Value { get; set; }58: }59: public class Language60: {61: public LanguageConfig Config { get; set; }62: private IDbContext _Db;63: private IDbContext Db64: {65: get66: {67: _Db = new DbContext().ConnectionString(Config.ConnectionString, Config.DbProviderType);68: return _Db;69: }70: }71: private Dictionary<string, Dictionary<string, string>> _KeyValue;72: public Language(LanguageConfig config)73: {74: Config = config;75: _KeyValue = new Dictionary<string, Dictionary<string, string>>();76:77: //加载多语言资源78: List<string> langs = new List<string>();79: DataTable dt = Db.Sql(string.Format(@"select [key]{0}80: from T_KEY_VALUE81: where SYSTEM_NAME='{1}'82: group by [KEY]", GetLangColumn(ref langs), config.SystemName))83: .QueryDataTable();84: foreach (DataColumn column in dt.Columns)85: {86: if (column.ColumnName.ToUpper() == "KEY")87: continue;88:89: Dictionary<string, string> dic;90: if (!_KeyValue.TryGetValue(column.ColumnName,out dic))91: {92: dic = new Dictionary<string, string>();93: _KeyValue.Add(column.ColumnName, dic);94: }95: foreach (DataRow row in dt.Rows)96: {97: if (dic.ContainsKey(row["key"].ToString()))98: {99: dic[row["key"].ToString()] = row[column.ColumnName].ToString();100: }101: else102: {103: dic.Add(row["key"].ToString(), row[column.ColumnName].ToString());104: }105: }106: }107:108:109: }110: private string GetLangColumn(ref List<string> langs)111: {112: string sql = "";113: DataTable dt = Db.Sql("select * from T_Language where status='1'").QueryDataTable();114: if (dt != null && dt.Rows.Count > 0)115: {116: foreach (DataRow item in dt.Rows)117: {118: sql += string.Format(",MAX(case LANGUAGE_VALUE when '{0}' then VALUE else '' end) as '{0}'",item["value"]);119: langs.Add(item["value"].ToString());120: }121: }122: return sql;123: }124: public List<LanguageNameValuePair> GetLanguageList()125: {126: List<LanguageNameValuePair> list = null;127: DataTable dt = Db.Sql("select * from T_Language where status='1'").QueryDataTable();128: if (dt != null && dt.Rows.Count > 0)129: {130: list = new List<LanguageNameValuePair>();131: foreach (DataRow item in dt.Rows)132: {133: list.Add(new LanguageNameValuePair() { Name = item["name"].ToString(), Value = item["value"].ToString() });134: }135: }136: return list;137: }138: public string this[string key]139: {140: get141: {142: return _KeyValue[Config.GetLanguage().ToUpper()][key];143: }144: }145: }146: }4、使用说明
开启服务端:
客户端调用:1: LangInstance.Start(new LanguageConfig() { SystemName = "a", ConnectionString = "Data Source=.;Initial Catalog=test;User ID=sa;Password=123456", DbProviderType = FluentData.DbProviderTypes.SqlServer, GetLanguage = null });2: LangInstance.Start();1: //添加按钮上的文字显示2: btnAdd.Text = LangInstance.Lang["add"];