分享
 
 
 

.net多语言和数据集内多数据表的处理(3)

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

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()包办掉这一切。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有