Tornando al problema della localizzazione visto nel post precedente.
In questo caso devo estrarre una singola notizia con tutte le sue localizzazioni; questa è una tipica situazione che si verifica a livello di (back end), dove l’utente vuole avere la possibilità di modificare le informazioni generali della notizia e le informazioni relative alle versioni localizzate, ottenendo la query (vedi codice).
1: DECLARE @CultureIdDefault AS INT = 16;
2: DECLARE @NewsId AS UNIQUEIDENTIFIER = '51C0E6DF-58B7-4913-A156-9A6196C3FBC1';
3:
4: SELECT NewsGenerale.Data, NewsGenerale.ImmagineUrl, NewsGenerale.Url,
5: NewsLocaleDefault.CultureId AS CultureIdLocaleDefault,
6: NewsLocaleDefault.ImmagineAltTesto AS ImmagineAltTestoLocaleDefault,
7: NewsLocaleDefault.Titolo AS TitoloLocaleDefault,
8: NewsLocaleDefault.Abstract AS AbstractLocaleDefault,
9: NewsLocaleDefault.Testo AS TestoLocaleDefault,
10: NewsLocale.CultureId AS CultureIdLocale,
11: NewsLocale.ImmagineAltTesto AS ImmagineAltTestoLocale,
12: NewsLocale.Titolo AS TitoloLocale,
13: NewsLocale.Abstract AS AbstractLocale,
14: NewsLocale.Testo AS TestoLocale
15: FROM (
16: SELECT NewsId, Visibile, Data, ImmagineUrl, Url
17: FROM News
18: WHERE NewsId = @NewsId
19: ) AS NewsGenerale INNER JOIN
20: (
21: SELECT NewsId, CultureId, ImmagineAltTesto, Titolo, Abstract, Testo
22: FROM NewsLocale AS NewsLocale_2
23: WHERE (NewsId = @NewsId) AND (CultureId = @CultureIdDefault)
24: ) AS NewsLocaleDefault ON NewsGenerale.NewsId = NewsLocaleDefault.NewsId LEFT OUTER JOIN
25: (
26: SELECT NewsId, CultureId, ImmagineAltTesto, Titolo, Abstract, Testo
27: FROM NewsLocale AS NewsLocale_1
28: WHERE (NewsId = @NewsId) AND (CultureId <> @CultureIdDefault)
29: ) AS NewsLocale ON NewsGenerale.NewsId = NewsLocale.NewsId
Questa query permette di estrarre in un unico passaggio la notizia identificata dal NewsId con tutte le sue localizzazioni, per distinguere la lingua di default dalle altre localizzazioni vengono utilizzati due join; il primo un INNER JOIN che permette di recuperare i dati localizzati nella lingua di default, il secondo un LEFT OUTER JOIN che permette di recuperare i dati localizzati nelle altre lingue.
Con questa query ottengo tante righe quante sono le localizzazioni presenti, quindi i dati generali della notizia e i dati localizzati nella lingua di default vengono ripetuti ottenendo una ridondanza di dati, nel caso in cui i dati relativi alla notizia siano presenti solo nella lingua di default otterremo una riga dove i dati relativi alla localizzazioni saranno NULL.
La notizia completa è un’entità composta da una classe contenente i dati generali della notizia, e da una lista di classi contenenti le localizzazioni della notizia.
La notizia completa viene costruita utilizzando un ciclo. I dati generali della notizia ed i dati localizzati nella lingua di default vengono recuperati la prima volta che viene eseguito il ciclo mentre i dati localizzati vengono recuperati ogni volta che il ciclo viene eseguito (“vedi codice”).
1: boNewsCompleta nc = new boNewsCompleta();
2: nc.ParteDeLoc = new boNewsDeLoc();
3: nc.ParteLocale = new List<boNewsLocale>();
4: boNewsLocale nl;
5:
6: SqlDataReader r;
7: bool primaVolta = true;
8: string msg;
9: while (r.Read())
10: {
11: //Verifica se è la prima volta che si entra nel ciclo
12: if (primaVolta)
13: {
14: //Notizia generale
15: nc.ParteDeLoc.Data = (DateTime)r["Data"];
16: nc.ParteDeLoc.ImmagineUrl = (String)r["ImmagineUrl"];
17: nc.ParteDeLoc.Url = (String)r["Url"];
18:
19: //Notizia localizzata nella lingua di default
20: nl = new boNewsLocale();
21: nl.CultureId = (int)r["CultureIdLocaleDefault"];
22: nl.ImmagineAltTesto = (String)r["ImmagineAltTestoLocaleDefault"];
23: nl.Titolo = (String)r["TitoloLocaleDefault"];
24: nl.Abstract = (String)r["AbstractLocaleDefault"];
25: nl.Testo = (String)r["TestoLocaleDefault"];
26: nc.ParteLocale.Add(nl);
27:
28: //Imposta il flag a false
29: primaVolta = false;
30: }
31:
32: //Notizia localizzata
33: nl = new boNewsLocale();
34: nl.CultureId = (r["CultureIdLocale"] is DBNull) ? 0 : (int)r["CultureIdLocale"];
35: nl.ImmagineAltTesto = (r["ImmagineAltTestoLocale"] is DBNull) ? String.Empty : (String)r["ImmagineAltTestoLocale"];
36: nl.Titolo = (r["TitoloLocale"] is DBNull) ? String.Empty : (String)r["TitoloLocale"];
37: nl.Abstract = (r["AbstractLocale"] is DBNull) ? String.Empty : (String)r["AbstractLocale"];
38: nl.Testo = (r["TestoLocale"] is DBNull) ? String.Empty : (String)r["TestoLocale"];
39:
40: //Verifica se la notizia localizzata è stata creata correttamente
41: if (!nl.IsNull(out msg))
42: {
43: nc.ParteLocale.Add(nl);
44: }
45: }