Lezione 5 – Creare Tabelle Database
Come abbiamo già fatto per gli utenti e i ruoli possiamo inserire nuove tabelle per la gestione delle attività del sito e inizializzarle con dati di default.
Completiamo la base di utilizzo dei dati utente inserendo una tabella Country con una piccolo range di stati internazionali. Per prima cosa creiamo una nuova classe Country (file Country.cs) nel folder Models.
public class Country
{
[Required, Key]
public int Id { get; set; }
[StringLength(69), Display(Name = "Nome")]
public string Name { get; set; }
[StringLength(2)]
public string TwoLetterIsoCode { get; set; }
[StringLength(3)]
public string ThreeLetterIsoCode { get; set; }
[StringLength(69)]
public string ShippingType { get; set; }
public bool LocalShipping { get; set; }
public bool AllowsShipping { get; set; }
public bool Published { get; set; }
}
Inserito il codice della classe Country per permettere al First Code Migration di utilizzare la classe dobbiamo definire l’oggetto DbSet all’interno del ApplicationDbContext e modificarlo come segue:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<FoodShop.Models.Country> Countries { get; set; }
}
Facciamo una Build di verifica e possiamo passare nella Package Manager Console per aggiungere una nuova migrazione con “ add-migration country ”.
Fatto update-database andiamo ad inserire del codice per fare la seed della tabella Country. Nel file SeedData.cs inserieamo il metodo SeedCountries.
public static void SeedCountries(IServiceProvider serviceProvider)
{
var context = new ApplicationDbContext(serviceProvider.GetRequiredService<DbContextOptions<ApplicationDbContext>>());
if (context.Countries.Any())
{
return; // DB has been seeded
}
context.Countries.AddRange(
new Country
{
Name = "Italia",
TwoLetterIsoCode = "IT",
ThreeLetterIsoCode = "ITA",
ShippingType = "Regional",
LocalShipping = Convert.ToBoolean("true"),
AllowsShipping = Convert.ToBoolean("true"),
Published = Convert.ToBoolean("true")
},
new Country
{
Name = "Germany",
TwoLetterIsoCode = "DE",
ThreeLetterIsoCode = "DEU",
ShippingType = "State",
LocalShipping = Convert.ToBoolean("true"),
AllowsShipping = Convert.ToBoolean("true"),
Published = Convert.ToBoolean("true")
},
new Country
{
Name = "France",
TwoLetterIsoCode = "FR",
ThreeLetterIsoCode = "FRA",
ShippingType = "State",
LocalShipping = Convert.ToBoolean("true"),
AllowsShipping = Convert.ToBoolean("true"),
Published = Convert.ToBoolean("true")
},
new Country
{
Name = "Spain",
TwoLetterIsoCode = "ES",
ThreeLetterIsoCode = "ESP",
ShippingType = "State",
LocalShipping = Convert.ToBoolean("true"),
AllowsShipping = Convert.ToBoolean("true"),
Published = Convert.ToBoolean("true")
},
new Country
{
Name = "United Kingdom",
TwoLetterIsoCode = "GB",
ThreeLetterIsoCode = "GBR",
ShippingType = "StateFar",
LocalShipping = Convert.ToBoolean("true"),
AllowsShipping = Convert.ToBoolean("true"),
Published = Convert.ToBoolean("true")
}
);
context.SaveChangesAsync().Wait();
}
Adesso non ci resta che utilizzare il metodo nel Program.cs.
try
{
//var context = serviceProvider.GetRequiredService();
//context.Database.Migrate();
SeedData.InitializeIdentity(serviceProvider);
SeedData.SeedCountries(serviceProvider);
}
Lanciamo il Debug e dopo l’apertura della HomePage chiudiamo e verifichiamo in SSMS le modifiche.
Quello fatto per Country lo applicheremo ad altre due tabelle: Banner e Notizia.
Il codice della classe Banner segue nella textbox.
public class Banner
{
[Required, Key]
public int Id { get; set; }
[Required, StringLength(69), Display(Name = "ID Pagina")]
public string IdBanner { get; set; }
[Required, StringLength(69), Display(Name = "File Name")]
public string IdFile { get; set; }
[StringLength(3), Display(Name = "Ext"), DefaultValue("jpg")]
public string BannerExtension { get; set; }
[DefaultValue(1)]
public int? NumImg { get; set; }
[DefaultValue(0)]
public int? Carusel_Inteval { get; set; }
[DefaultValue("#")]
public string URL { get; set; }
[DefaultValue("Title")]
public string Titolo { get; set; }
}
Il codice della classe Notizia segue nella textbox.
public class Notizia
{
[Key]
public int Id { get; set; }
[StringLength(92), Display(Name = "Titolo")]
public string Title { get; set; }
[StringLength(184), Display(Name = "Sotto Titolo")]
public string Subtitle { get; set; }
[DataType(DataType.MultilineText)]
public string Newtext { get; set; }
[DisplayName("Data di Registrazione")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = false)]
[Column(TypeName = "datetime2")]
public DateTime DateCreated { get; set; }
[DefaultValue(false)]
public bool Deleted { get; set; }
}
Per le news abbia utilizzato Notizia per “new” è un namespace di c# per evitare inutili conflitti. Questa regola va sempre tenuta in considerazione visto che dopo essere scritto il codice va anche interpretato per capirne l’esecuzione e complicarsi la vita inutilmente non serve a nessuno, specialmente quando ritorniamo a leggerlo dopo diversi mesi e non ricordiamo più cosa volevamo fare.
Aggiungiamo ad ApplicationDbContext i due DbSet.
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<FoodShop.Models.Country> Countries { get; set; }
public DbSet<FoodShop.Models.Banner> Banners { get; set; }
public DbSet<FoodShop.Models.Notizia> Notizias { get; set; }
}
Siamo pronti per la migrazione nella PMC: add-migration banner , update-database.
Aggiungere i metodi per l’inizializzazione nella classe SeedData.
public static void SeedBanners(IServiceProvider serviceProvider)
{
using var context = new ApplicationDbContext(serviceProvider.GetRequiredService<DbContextOptions<ApplicationDbContext>>());
if (context.Banners.Any())
{
return; // DB has been seeded
}
context.Banners.AddRange(
new Banner
{
IdBanner = "homepagehead",
IdFile = "vs2022.png",
URL = "https://visualstudio.microsoft.com",
Titolo = "Visual Studio 2022"
},
new Banner
{
IdBanner = "homepagehead",
IdFile = "aspnetcore.png",
URL = "https://docs.microsoft.com/it-it/aspnet/core/introduction-to-aspnet-core?view=aspnetcore-6.0",
Titolo = "Asp.Net Core"
},
new Banner
{
IdBanner = "homepagehead",
IdFile = "entiryfrm.png",
URL = "https://docs.microsoft.com/it-it/ef/core/get-started/overview/first-app?tabs=netcore-cli",
Titolo = "Entity Framework Core"
}
);
context.SaveChangesAsync().Wait();
}
public static void SeedNotizias(IServiceProvider serviceProvider)
{
using var context = new ApplicationDbContext(serviceProvider.GetRequiredService<DbContextOptions<ApplicationDbContext>>());
if (context.Notizias.Any())
{
return; // DB has been seeded
}
context.Notizias.AddRange(
new Notizia
{
Title = "Divina Commedia",
Subtitle = "Inferno, Canto Primo",
Newtext = "Nel mezzo del cammin di nostra vita mi ritrovai per una selva oscura ché la diritta via era smarrita. Ahi quanto a dir qual era è cosa dura esta selva selvaggia e aspra e forte che nel pensier rinova la paura! Tant'è amara che poco è più morte; ma per trattar del ben ch'i' vi trovai, dirò de l'altre cose ch'i' v'ho scorte. Io non so ben ridir com'i' v'intrai, tant'era pien di sonno a quel punto che la verace via abbandonai. Ma poi ch'i' fui al piè d'un colle giunto, là dove terminava quella valle che m'avea di paura il cor compunto, guardai in alto, e vidi le sue spalle vestite già de' raggi del pianeta che mena dritto altrui per ogne calle...",
DateCreated = DateTime.Now
},
new Notizia
{
Title = "Divina Commedia",
Subtitle = "Inferno, Canto Secondo",
Newtext = "Lo giorno se n'andava, e l'aere bruno toglieva li animai che sono in terra da le fatiche loro; e io sol uno sì del cammino e sì de la pietate, che ritrarrà la mente che non erra. O muse, o alto ingegno, or 'aiutate; o mente che scrivesti ciò ch'io vidi, qui si parrà la tua nobilitate. Io cominciai: «Poeta che mi guidi, guarda la mia virtù s'ell' è possente, prima ch'a l'alto passo tu mi fidi. Tu dici che di Silvïo il parente, corruttibile ancora, ad immortale secolo andò, e fu sensibilmente. Però, se l'avversario d'ogne male cortese i fu, pensando l'alto effetto ch'uscir dovea di lui, e 'l chi e 'l quale non pare indegno ad omo 'intelletto; ch'e' fu de l'alma Roma e di suo impero ne l'empireo ciel per padre eletto: la quale e 'l quale, a voler dir lo vero, fu stabilita per lo loco santo u' siede il successor del maggior Piero...",
DateCreated = DateTime.Now
},
new Notizia
{
Title = "Divina Commedia",
Subtitle = "Inferno, Canto Terzo",
Newtext = "'Per me si va ne la città dolente, per me si va ne l'etterno dolore, per me si va tra la perduta gente. Giustizia mosse il mio alto fattore; fecemi la divina podestate, la somma sapïenza e 'l primo amore. Dinanzi a me non fuor cose create se non etterne, e io etterno duro. Lasciate ogne speranza, voi ch'intrate'. Queste parole di colore oscuro vid' ïo scritte al sommo d'una porta; per ch'io: «Maestro, il senso lor m'è duro». Ed elli a me, come persona accorta: «Qui si convien lasciare ogne sospetto; ogne viltà convien che qui sia morta. Noi siam venuti al loco ov' i' t'ho detto che tu vedrai le genti dolorose c'hanno perduto il ben del'intelletto». E poi che la sua mano a la mia puose con lieto volto, ond' io mi confortai, mi mise dentro a le segrete cose. Quivi sospiri, pianti e alti guai risonavan per l'aere sanza stelle, per ch'io al cominciar ne lagrimai...",
DateCreated = DateTime.Now
},
new Notizia
{
Title = "Divina Commedia",
Subtitle = "Inferno, Canto Quarto",
Newtext = "Ruppemi l'alto sonno ne la testa un greve truono, sì ch'io mi riscossi come persona ch'è per forza desta; e l'occhio riposato intorno mossi, dritto levato, e fiso riguardai per conoscer lo loco dov' io fossi. Vero è che 'n su la proda mi trovai de la valle d'abisso dolorosa che 'ntrono accoglie d'infiniti guai. Oscura e profonda era e nebulosa tanto che, per ficcar lo viso a fondo, io non vi discernea alcuna cosa. «Or discendiam qua giù nel cieco mondo», cominciò il poeta tutto smorto. «Io sarò primo, e tu sarai secondo». E io, che del color mi fui accorto, dissi: «Come verrò, se tu paventi che suoli al mio dubbiare esser conforto?». Ed elli a me: «L'angoscia de le genti che son qua giù, nel viso mi dipigne quella pietà che tu per tema senti. Andiam, ché la via lunga ne sospigne». Così si mise e così mi fé intrare nel primo cerchio che l'abisso cigne...",
DateCreated = DateTime.Now
}
);
context.SaveChangesAsync().Wait();
}
E chiamarli all’interno di Program.cs.
try
{
//var context = serviceProvider.GetRequiredService<ApplicationDbContext>();
//context.Database.Migrate();
SeedData.InitializeIdentity(serviceProvider);
SeedData.SeedCountries(serviceProvider);
SeedData.SeedBanners(serviceProvider);
SeedData.SeedNotizias(serviceProvider);
}
Lanciamo il Debug e poi controlliamo SSMS per le modifiche.
Nella prossima lezione tratteremo la visualizzazione della HomePage e l’uso del linguaggio HTML per ottenere le impostazioni grafiche desiderate.