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

原创 2004年02月06日 10:02:00
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()包办掉这一切。

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

2                  考虑一个数据集中有多个数据表的问题 好处是什么? 很重要的一点,可以很方便的导航取得相关的信息,如Province.GetCityRows ()可以获得这个省下面...
  • lornshrimp
  • lornshrimp
  • 2004年02月07日 22:56
  • 778

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

1        考虑多语言的问题 对于多语言,需要考虑两个方面,一个是界面,一个是数据库信息,对于界面的多语言问题比较简单,只要建立相应的资源文件就可以了,这里不再多说;比较复杂的是数据库信息的多语...
  • lornshrimp
  • lornshrimp
  • 2004年02月07日 22:56
  • 903

android开发 多语言和国际化

我们建好一个android 的项目后,默认的res下面 有layout、values、drawable等目录 这些都是程序默认的资源文件目录,如果要实现多语言版本的话,我们就要添加要实现语言的对...
  • lanjianhun
  • lanjianhun
  • 2012年12月24日 18:37
  • 9957

wpf多语言和换肤

http://www.cnblogs.com/bdstjk/archive/2013/05/11/3072523.html   http://www.cnblogs.com/scy251147/arc...
  • liuhaisong290
  • liuhaisong290
  • 2013年08月25日 22:55
  • 333

多语言和自定义CSS

最近在一个SharePoint 2010项目中发现,在装了英文、日文语言包之后,在网站设置的语言设置中,选择备用语言的时候,系统返回一个异常,大意是包含自定义样式表(CSS)的网站不支持多语言。 之...
  • lance_lot1
  • lance_lot1
  • 2012年09月10日 15:48
  • 404

DotNet的多语言和本地化

 感觉非常方便,这也是一直以来MS的优势,集成的优势最近一个小项目用到VS2005,用了点AJAXTOOL,很简单的2个设置就搞定了不同情况的不同语言提示显示信息在SCRIPTMANAGER的属性里设...
  • realonedot
  • realonedot
  • 2008年12月15日 16:51
  • 189

用.xsd (数据集)生成数据层(DAL)代码

首先新建二个项目(BLL:逻辑层,DAL:数据层):如下图然后在DAL(数据层)中新建一个.xsd数据集(名字可以自己定义):如下图创建好了如下:打开这个已创建好的TestDataSet.xsd:如下...
  • lisenustc
  • lisenustc
  • 2009年11月30日 16:24
  • 3693

android开发 多语言和国际化(转)

我们建好一个android 的项目后,默认的res下面 有layout、values、drawable等目录 这些都是程序默认的资源文件目录,如果要实现多语言版本的话,我们就要添加要实现语言的对...
  • zhuiqiuk
  • zhuiqiuk
  • 2015年08月05日 17:42
  • 475

Android支持多国语言化Values命名

android多国语言文件夹文件汇总如下: 维吾尔文(中国):values-ug-rCN 中文(中国):values-zh-rCN 中文(台湾):values-zh-rTW 中...
  • u010687392
  • u010687392
  • 2015年05月18日 12:25
  • 1711

C# DataSet(内存中的数据集)

DataSet 中有多个 DataTable;DataTable 中有多个DataColumn (列名),多个Rows (数据行)。 using System; using System.Colle...
  • houyanhua1
  • houyanhua1
  • 2017年12月13日 17:44
  • 123
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:.net多语言和数据集内多数据表的处理(3)
举报原因:
原因补充:

(最多只允许输入30个字)