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
关键词:.net多语言与数据集内多数据表的处理(3)