Chi di voi ha mai avuto a che fare con localizzazione e
globalizzazione di applicazioni .NET sa bene come funziona il meccanismo del
fallback delle culture. In soldoni, per chi non lo sapesse si tratta di quel
pricipio per cui se tra le risorse non esiste quella nella cultura che è
richiesta, il framework provvedde a trovarne una il più possibile adatta. Quello
che forse non è chiaro a tutti è che implementando l'expression builder di cui
ho parlato in un post
precedente si perde questa utile
funzionalità ed è necessario scrivere del codice per gestire l'eventualità. Io
quest'oggi mi sono trovato in questa situazione e nel cercare di gestirla ho
approfondito il modo con cui il framework codifica le culture e ho tratto da
questo approfondimento una singola query che è in grado di risolvere il
problema.
Se avete la pazienza di guardare le proprietà della classe
CultureInfo noterete che essa ne espone una che si chiama LCID
. L'LCID è un
codice numerico a 32 bit che esprime la medesima forma che siamo abituati a
vedere con i codici ISO che normalmente denominano le culture del framework. Di
questi 32 bit infatti i primi 16 vengono utilizzati per esprimere il LanguageID mentre i
seguenti 8 bit contengono il SortID. Ad esempio nel caso dell'inglese vedremo che LCID
è 1033. Se convertiamo questo numero in esadecimale troveremo che equivale a 0x0409.
La cosa notevole è che prendendo tutte le varianti della lingua
inglese avremo:
English |
0009 |
English - United States |
0409 |
English - United Kingdom |
0809 |
English - Australia |
0c09 |
English - Canada |
1009 |
English - New Zealand |
1409 |
English - Ireland |
1809 |
English - South Africa |
1c09 |
English - Caribbean |
2409 |
English - Belize |
2809 |
English - Trinidad |
2c09 |
English - Zimbabwe |
3009 |
English - Philippines |
3409 |
English - Indonesia |
3809 |
English - Hong Kong SAR |
3c09 |
English - India |
4009 |
English - Malaysia |
4409 |
English - Singapore |
4809 |
In buona sostanza tutte le varianti della lingua inglese
terminano per 09 e dispongono di un codice numerico che le ordina. Lo stesso
principio si applica a tutte le altre culture. Ecco quindi che in breve ho
prodotto una query che dato un LCID in ingresso trova quello disponibile che più
si avvicina. La query sfrutta gli operatori booleani per separare dapprima
LangId e SortId, usa il LangId del parametro di ingresso per isolare le culture
analoghe e poi ordinando per SortId discendente prende la prima il cui SortId
sia minore o uguale a quello fornito.
create function dbo.CultureGetFallbackByLCID(@lcid int)
returns int
as
begin
return
(
select top 1 SortID | LangID from
(
select distinct
Culture & 0xff00 as SortID,
Culture & 0xff as LangID
from
AvailableCultures
) A
where
A.LangID = @lcid & 0xff and
A.SortID <= @lcid & 0xff00
order by SortID desc
);
end;
Naturalmente la query può fornire in uscita anche NULL
qualora non trovi una cultura che si avvicina a quella fornita. E' questo il
caso in cui si dovrà adottare la cultura neutra ovvero quella definita per il
fallback finale.
powered by IMHO 1.3