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: get
66: {
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_VALUE
81: 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: get
141: {
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"];