.net多語言和資料集內多資料表的處理(3)

來源:互聯網
上載者:User
資料 3 考慮以上兩種情況的綜合
當以上兩種情況湊在一塊的時候,情況還會複雜一些,因為在我們的這個解決方案中,多語言和資訊的主體是採用的松耦合,如果不採用松耦合就不能保證其通用性和可擴充性,但是採用了松耦合在資料集中多表操作時又會產生麻煩。
因為松耦合,所以在資料集中自動級連更新的時候並不能夠自動更新,修改還無所謂,我們只要保證和多語言表關聯的那個Guid不變就可以了,但是刪除呢?我們總不能把資訊主體刪除了卻又把多語言資料留著吧,更麻煩的是因為資料已經刪除,我們很難知道刪除之前與多語言資料表關聯的Guid是多少。而且我們需要把對資訊主體的刪除和多語言資料的刪除放到一個事務中,相信誰都不會希望程式偶然出錯資訊主體未被刪除的時候多語言資料都被刪除了。而且,我們還要實現前面曾說過的一個目標:每個使用者都只需要維護自己用的這種語言的記錄資訊就可以了,而不用考慮其他語言的問題,也可以非常方便的即使系統運行了一段時間後再次添加支援的語言,不需要在添加記錄的事後就需要添加所有語言的版本,只在需要的時候才添加相應語言的版本,從而使資料庫記錄數盡量的少。
好了,我們知道了需求,然後該怎麼做呢?看下面的代碼:
在從資料庫擷取資料時:
public AddressData GetAddress(string languageCode)
{
AddressData ds = new AddressData();

SqlDataAdapter DARegion = new SqlDataAdapter(AddressSQL.strGetRegion,SQLConfig.DataBaseConnection);
DARegion.Fill(ds.Region);

SqlDataAdapter DACountry = new SqlDataAdapter(AddressSQL.strGetCountry,SQLConfig.DataBaseConnection);
DACountry.Fill(ds.Country);

SqlDataAdapter DAProvince = new SqlDataAdapter(AddressSQL.strGetProvince,SQLConfig.DataBaseConnection);
DAProvince.Fill(ds.Province);

SqlDataAdapter DACity = new SqlDataAdapter(AddressSQL.strGetCity,SQLConfig.DataBaseConnection);
DACity.Fill(ds.City);

SqlDataAdapter DAPort = new SqlDataAdapter(AddressSQL.strGetPort,SQLConfig.DataBaseConnection);
DAPort.Fill(ds.Port);

RegionTypeData regionTypeDS = GetRegionType(languageCode);

foreach ( AddressData.RegionRow region in ds.Region)
{
if (!region.IsNameGuidNull())
{
region.Name = DBDisplayString.GetDisplay(region.NameGuid,languageCode,vDisplayTable);
}
if (regionTypeDS.RegionType.FindByRegionTypeID(region.RegionTypeID) != null)
{
region.RegionTypeName = regionTypeDS.RegionType.FindByRegionTypeID(region.RegionTypeID).Abbr;
}
}

foreach ( AddressData.CountryRow country in ds.Country)
{
if (!country.IsNameGuidNull())
{
country.Name = DBDisplayString.GetDisplay(country.NameGuid,languageCode,vDisplayTable);
}
}

foreach (AddressData.ProvinceRow province in ds.Province)
{
if (!province.IsNameGuidNull())
{
province.Name = DBDisplayString.GetDisplay(province.NameGuid,languageCode,vDisplayTable);
}
}

foreach (AddressData.CityRow city in ds.City)
{
if (!city.IsNameGuidNull())
{
city.Name = DBDisplayString.GetDisplay(city.NameGuid, languageCode,vDisplayTable);
}
}

foreach (AddressData.PortRow port in ds.Port)
{
if (!port.IsNameGuidNull())
{
port.Name = DBDisplayString.GetDisplay(port.NameGuid,languageCode,vDisplayTable);
}
}

return ds;
}
這樣,只需要通過一個單一的Name欄位便可以擷取使用者所用語言的資料了,而不用考慮使用者使用的到底是哪一種語言。這裡不在資料庫裡直接做join的原因是:這個擷取多語言資料的方法並不是直接把資料庫資料取出來那麼簡單,假如使用者要取的那種語言的某條資料恰好沒有呢?我們取了一個系統預設語言的資料,那麼哪一種是系統預設語言呢?可見如果這些都放在SQL中做的話,要傳入的參數會非常多,SQL語句會變得非常複雜,也就不利於封裝了,而且考慮到SQL語句調試的複雜性,我沒有選擇這麼做。
那麼把資料更新回資料庫又該怎麼辦呢?看下面的代碼:
private void DeleteDisplay(AddressData ds, Guid refGuid)
{
foreach (AddressData.AddressDisStrRow dis in ds.AddressDisStr.Select("RefGuid = '" +refGuid+ "'"))
{
dis.Delete();
}
}
private void DeletePort(AddressData ds, int portID)
{
if (!ds.Port.FindByPortID(portID).IsNameGuidNull())
{
DeleteDisplay(ds,ds.Port.FindByPortID(portID).NameGuid);
}
ds.Port.FindByPortID(portID).Delete();
}

private void DeleteCity(AddressData ds, int cityID)
{
if (!ds.City.FindByCityID(cityID).IsNameGuidNull())
{
DeleteDisplay(ds,ds.City.FindByCityID(cityID).NameGuid);
}
foreach (AddressData.PortRow port in ds.Port)
{
if ((int)port["CityID",DataRowVersion.Original] == cityID)
{
port.RejectChanges();
DeletePort(ds,port.PortID);
}
}
ds.City.FindByCityID(cityID).Delete();
}

private void DeleteProvince(AddressData ds, int provinceID)
{
if (!ds.Province.FindByProvinceID(provinceID).IsNameGuidNull())
{
DeleteDisplay(ds,ds.Province.FindByProvinceID(provinceID).NameGuid);
}
foreach (AddressData.CityRow city in ds.City)
{
if ((int)city["ProvinceID",DataRowVersion.Original] == provinceID)
{
city.RejectChanges();
DeleteCity(ds,city.CityID);
}
}
ds.Province.FindByProvinceID(provinceID).Delete();
}
public void UpdateProvince(AddressData ds, string languageCode)
{
SqlDataAdapter DAAddressDisStr = new SqlDataAdapter(AddressSQL.strGetAddressDisStr,SQLConfig.DataBaseConnection);
DAAddressDisStr.Fill(ds.AddressDisStr);

foreach(AddressData.ProvinceRow province in ds.Province)
{
if (province.RowState == DataRowState.Deleted)
{
province.RejectChanges();
DeleteProvince(ds,province.ProvinceID);
}
else if (province.RowState == DataRowState.Added || province.RowState == DataRowState.Modified)
{
if (province.IsNameNull() && !province.IsNameGuidNull())
{
DBDisplayString.SaveDisplay(languageCode,province.NameGuid,null,vDisplayTable);
}
else if (!province.IsNameNull())
{
if (province.IsNameGuidNull())
{
province.NameGuid = Guid.NewGuid();
}
DBDisplayString.SaveDisplay(languageCode,province.NameGuid,province.Name,vDisplayTable);
}
}
}
DataTableExtend[] dts = new DataTableExtend[4];
dts[0] = new DataTableExtend(ds.Port,"Port");
dts[1] = new DataTableExtend(ds.City, "City");
dts[2] = new DataTableExtend(ds.Province,"Province");
dts[3] = new DataTableExtend(ds.AddressDisStr,vDisplayTable);
SQLModify.ModifyDataBase(dts);
}
可以看出,這個操作會很麻煩,對於刪除操作而言,我們需要把該條記錄所有的多語言資料都刪掉,然後很不幸,對於資料集中已刪除了的記錄而言,雖然它還存在但卻不能訪問,更不幸的是,因為多資料表關聯的原因,我們甚至都不知道有多少資料被級連刪除了:(沒辦法,RejectChanges()吧,然後通過關聯找到所有被級連刪除的資料,把多語言資料都刪除掉,然後再刪除自身,注意到我這裡用到了Select方法,這是一個很方便的做法,減少了到資料庫的往返操作,從而以犧牲一些記憶體的代價節省了與資料庫痛心的時間。對於新增和修改操作,我們則負擔著另一項任務,即把Name欄位裡的資料根據使用者的當前語言,更新會資料庫相應的記錄中,這裡也會有很多種情況,如該欄位資料是新增的,預設語言的資料也沒有,當前語言的資料也沒有,或者是預設語言的資料有了當前語言的資料卻沒有,再或者使用者是把這個欄位的資料清空了,我們必須要找到多語言表中相應的記錄並刪除掉……等等,無奈,我們只好讓DBDisplayString.SaveDisplay()包辦掉這一切。

相關文章

Cloud Intelligence Leading the Digital Future

Alibaba Cloud ACtivate Online Conference, Nov. 20th & 21st, 2019 (UTC+08)

Register Now >

Starter Package

SSD Cloud server and data transfer for only $2.50 a month

Get Started >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。