產品的定位
做產品的都知道,是否支援多語言直接影響到產品的定位問題。
如果一個產品週期是一年的話,要完美支援多語言最少也得在加3個月!所需時間和頁面數量、資料庫表的數量和表的資料量成正比。
可以看出代價有多大,我們程式設計師就得和老闆嘮叨,做不得,成本太高。
如果前期不做,等到了後期專案表結構等都要重構,如果使用了大量的檢視對於多語言來說就是惡夢。
非資料庫方面的解決方案
請看我上一篇貼子 http://www.cnblogs.com/sunkaixuan/p/5699744.html
資料庫表的設計
對於多語言來說最重要的就是清單表的設計, 就拿簡歷來說吧,至少會用到十幾張清單表 (當然你也可以儲存在一張表裡用分類)
學歷表:小學、中學、大學、博士 等等
工作年限表:習實生,1年工作經驗,2年工作經驗等等
...
多語言架構清單表的設計誤區
如下圖這種設計是存在嚴重缺陷的,列來存語言難道我多一種語言就要加一列,顯然是不合理的
錯誤方案
正確的設計方案
、
名稱 清單ID 語言ID
Primary education 1 1
小學 1 2
middle school 2 1
初中 2 2
資料結構應該是這樣的至少,相同的東西是一樣的ID,名稱不一樣而已,產品架構千萬不要用列儲存。
這種表架構又會出一個問題
當使用語言ID來作為篩選時,就會遇到一個很大的問題,沒錯那就是檢視的JOIN問題,如果我在檢視裡面寫
人員表 JOIN 學歷表 ON 學歷表.ID=人員表.學歷ID AND 學歷表.語言ID=幾
沒法寫了對不,如果我在檢視裡寫了1那就意味著我查出來的清單都只會是一種語言(語言ID為1的那個語言)
檢視的作用
檢視相當於虛擬表,可以方便的複用,檢視還可以套檢視,並且檢視在索引合理的情況下,比單表查詢還要快。 (索引覆蓋就是一個很好的例子)
那怎麼辦呢?SqlSugar ORM已經為我們做好這一切
隨著ORM效能瓶頸的提升,都玩會了EMIT 快取這套,甚至拉姆達TO SQL都有開源專案 大大降低了ORM的門檻,SqlSugar也是拉姆達解析加EMIT玩的最早的ORM之一。
SqlSugar是為通用框架搭建而生,擁有了一定量的使用者,在6600萬高併發的測試中也得到了使用者的好評。
雖然也有很多朋友抱怨問題,大致會有兩個問題 實體轉換報錯,其實是欄位型別不配引起的或者更改了表結構沒有把.NET例項重啟因為有快取的原因。
我不能保證我的程式碼寫的多優雅,但能保證我寫的程式碼都能看懂。我寧可寫IF ELSE也不會寫讓我腦子在轉一圈的程式碼,我不會因為我一天能解決的問題去套一個使我花2天以上解決問題的設計模式,合理封裝便可,沒有過度設計。
SqlSugar在很多細節上都做過處理,比如執行緒安全、事務隔離等引數
使用SqlSugar ORM解決檢視問題
1、我們就把檢視語言ID設為1 (1為預設語言)
人員表 JOIN 學歷表 ON 學歷表.ID=人員表.學歷ID AND 學歷表.語言ID=1
2、我們可以使用 LanguageHelper.UpdateView(db.Language, db); 幫我們生成其它語言的檢視,只要使用在Application_Start執行一次便可以,當檢視發生變化也需要在調一次或者重啟程式
只要檢視原始碼中包含LanguageId=1的所有檢視都會建立出新的檢視並且把LanguageId=1替換成你想要的ID
3、他會根據引數生成一個新的檢視 原檢視名_$_EN ,新的檢視和原檢視一樣只是名稱和語言的值發生了變化
人員表 JOIN 學歷表 ON 學歷表.ID=人員表.學歷ID AND 學歷表.語言ID=2
4、var list=db.Qureyable<原檢視名>().ToList()
ORM會自動識別新的檢視進行查詢,生成的SQL如下 SELECT * FROM 新檢視名
下面是具體程式碼:
using (SqlSugarClient db = SugarDao.GetInstance())//開啟資料庫連線 { db.Language = new PubModel.Language() { LanguageValue=2,//多語言的值一般從COOKIES或SESSION取 Suffix="en"//多語言字尾同上 }; //給上面賦值後下面的程就可以使用了 int lanId=db.Language.LanguageValue; var list = db.Queryable<LanguageTest>().Where(it => it.LanguageId == lanId).ToList(); /****************************多語言檢視才是最大的問題***********************************/ //注意檢視裡裡怎麼辦呢?檢視裡面的JOIN用到語言表怎麼處理呢 //我們就寫一個簡單的檢視作為例子,程式碼如下 /*create view V_LanguageTest as select * from LanguageTest where LanguageId=1 */ //下面這程式碼寫到 application_start 不需要重複執行 LanguageHelper.UpdateView(db.Language, db); //執行完上面的程式碼會建立把所有帶LanguageId=1的檢視全部生成其它語言的檢視 //現在資料庫就有了 V_LanguageTest_$_en // V_LanguageTest_$_en結構如下 /*create view V_LanguageTest_$_en as select * from LanguageTest where LanguageId=2 */ //V_LanguageTest__$_en 是我SqlSugar自動幫你建立的 當檢視發生變化需要重新執行 LanguageHelper.UpdateView(db.Language, db); var list2=db.Queryable<V_LanguageTest>().ToList(); //生成的Sql等於 select * from V_LanguageTest_$_en db.Language.LanguageValue = 1;//我們在把LanguageValue改成1 db.Language.Suffix = null;//字尾清空 var list3 = db.Queryable<V_LanguageTest>().ToList(); //生成的Sql等於 select * from V_LanguageTest //注意當 Suffix為null時使用的原始檢視 //自定義檢視替換規則請看下面兩個引數 //db.Language.ReplaceViewStringKey 預設值為LanguageId=1 //db.Language.ReplaceViewStringValue 預設值為LanguageId = {0} }