3
Consider the combination of the above two cases
When the above two cases are in one, the situation will be more complex, because in our solution, the main body of multi-language and information is loose coupling, if it is not used loose coupling, it cannot guarantee the versatility and Scalability, but a loose coupling will have trouble when multiple meters in data sets.
Because of loosely coupled, it is not possible to automatically update when the automatic level update is updated in the data set. It doesn't matter if we guarantee that the GUID that is associated with multilingual tables will be, but delete? We can't delete the information subject, but it is more troublesome because the data has been deleted, and we are hard to know how much the GUID associated with multilingual data tables before deleting. And we need to put the deletion of the information body and the deletion of the multi-language data in a transaction. I believe that when the program is accidentally mistaken, the multi-language data is deleted when the main body is not deleted. Moreover, we also have to achieve a goal that has been said: Each user only needs to maintain the record information of this language itself, without considering the problem of other languages, it can also be very convenient even if the system is running After a period of time, add a supported language. You don't need to add a version of all languages after you add a record. You can only add the corresponding language version, so that the database record number is less.
Ok, we know the needs, then what should I do? Look at the following code:
When getting data from the database:
Public AddressData Getdress (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 (addresssssql.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);
RegionTypedTyPeds = 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;
}
In this way, only the data of the language used by the user can only be used through a single Name field, without considering which language is used. The reason for doing Join directly here is that this method of obtaining multilingual data is not as simple as directly putting the database information, if the language of the language you want to take is not? We took a system default language data, then which one is the system default language? It can be seen that if these are done in SQL, there is a lot of parameters to be incompatible, and the SQL statement will become very complicated, which is not conducive to encapsulation, and considering the complexity of the SQL statement debugging, I didn't choose to do this. .
So what should I do if the data update back the database? Look at the following code:
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.findbyCID (cityid) .isnameguidnull ())
{
Deletedisplay (DS, DS.CITY.FindByCityId .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 Province)
{
IF (! ds.province.findbyProvinceId (provinceId) .isnameguidnull ())
{
DeleteDisplay (DS, DS.Province.FindByProvinceId) .nameguid;
}
Foreach (addressData.cityrow city in ds.city)
{
IF ((int) city ["provinceId", DATAROWVERSION.ORIGINAL] == provinceID)
{
City.rejectchanges ();
DeleteCity (DS, City.cityID);
}
}
DS.Province.FindByProvinceId (province) .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 ())
{
pROVINCE.ISNameGuidnull ())
{
province.nameguid = guid.newguid ();
}
DBDisplayString.savedisplay (LanguageCode, province.nameguid, provable.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);
}
It can be seen that this operation will be very trouble. For deletion operations, we need to delete all the multi-language data to record all multi-language data, and unfortunately, for the record of deleted records, although it still exists But it is not accessible, even more unfortunate because we don't even know how much data is deleted in the class: (there is no way, rejectchanges (), then find all levels to delete Data, delete multi-language data, then delete itself, notice that I use SELECT method here, which is a very convenient practice, which reduces the round-trip operation of the database, which saves the cost of sacrificing some memory. Time with database pain. For new and modified operations, we will bear another task, that is, in the records of the Name field according to the user's current language, there will be many situations here. If the field data is new, the data of the default language is not, the current language is not, or the data of the default language has the current language of the current language, or the user is the data of this field. Empty, we must find the corresponding records in the multi-language table and delete ... Wait, helpless, we have to let DBDISPLAYSTRING.SAVEDISPLAY () package all.