產品的定位 做產品的都知道,是否支持多語言直接影響到產品的定位問題。 如果一個產品周期是一年的話,要完美支持多語言最少也得在加3個月!所需時間和頁面數量、資料庫表的數量和表的數據量成正比。 可以看出代價有多大,我們程式員就得和老闆嘮叨,做不得,成本太高。 如果前期不做,等到了後期項目表結構等都要重構 ...
產品的定位
做產品的都知道,是否支持多語言直接影響到產品的定位問題。
如果一個產品周期是一年的話,要完美支持多語言最少也得在加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} }
SqlSugar學習下載地址:
http://www.cnblogs.com/sunkaixuan/p/5654695.html