in

dotNet Umbria

Il primo User Group in Umbria sul mondo .Net

Andrea Cruciani' blog

parlando di .Net: i miei libri, architettura, il Web, le applicazioni mobile, Wpf, MicroFramework...

February 2008 - Posts

  • Book review: Pro Linq - Language Integrated Query in C# 2008

    La serie "Pro" di APress mi piace molto, ho già apprezzato i volumi su WPF e WCF ma, a chi fosse interessato a Linq, non posso che segnalare questo nuovo volume sull'argomento scritto da Joseph C. Rattz. L'autore affronta la problematica partendo da un concetto interessante: poniamo l'attenzione sui punti cruciali prima di approfondire i presupposti della tecnologia. Questo approccio "top down" è estremamente efficace soprattutto per un libro di approfondimento come quelli della serie "pro".

    Gli argomenti sono trattati con grande chiarezza e con un grado di dettaglio più che sufficiente (a volte anche estremo come la parte in cui viene descritta tutta la grammatica delle query). In particolar modo ho personalmente molto gradita la parte di Linq to Objects, in cui vengono espressi molti dei concetti che saranno comuni a tutto Linq, in particolare l'attenzione nella descrizione degli operatori che vengono divisi in Deferred Operators e NonDeferred Operators. Parte da leone, ovviamente, la fa Linq to Sql con 7 capitoli ad esso dedicati.

     

    Un libro che non posso che consigliare a tutti coloro che vogliono approfondire in modo organico Linq.

    Titolo: Pro Linq - Language Integrated Query in C# 2008
    Autore: APress
    Data pubblicazione: Novembre 2007
    Pagine: 600

  • Linq to SQL InheritanceMapping

    L'altro giorno mi sono ritrovato a fare una chiacchierata con Simone, grande supporter di NHibernate, su alcune delle features di Linq e ci siamo trovati concordi nel dire che l'Inheritance mapping è una tra le più interessanti per i nostri porgetti reali.
    Per chi non avesse ancora visto Linq to Sql và fatta una piccola premessa: il modo più immediato ed intuitivo di mappare le tabelle del nostro db (Linq to Sql al momento supporta solo Sql Server) è quello di aggiungere un nuovo item al nostro progetto di tipo "Linq to Sql classes", di creare una connessione in Server Explorer al db che vogliamo utilizzare e tramite drag&drop trascinare le tabelle che ci interessano. Vediamo il risultato in figura:

     

    Questo tipo di mapping prevede l'utilizzo degli attributi per legare le proprietà delle entità generate con i campi presenti nelle tabelle del db. Alternativamente è possibile utilizzare un mapping esterno su files Xml che però non ci interessa per l'esempio corrente.

    L'idea è quella di avere una classe per rappresentare un generico item di una rubrica (chiamato fantasiosamente Rubrica) e di andare a specializzarlo in classi specifiche per la rurbrica dei fornitori, clienti e magari delle aziende. VS2008 ci genera una classe Rurbica che mappa in modo semplice la nostra tabella. Ereditiamo qundi questo tipo nelle classi che rappresentano Clienti,Fornitori ed Aziende:

     

    All'interno della tabella esiste un campo denominato ContactType (tinyint ovvero byte in .Net) che ho stabilito mi specificherà il tipo di contatto. Ora voglio che Linq to Sql mi restituisca l'entità giusta a seconda del valore del ContactType, per fare questo devo agire in due step sulla classe Rubrica generatami da VS2008.

    Sulla proprietà che mi mappa il ContentType imposto l'attributo IsDiscriminator a true per l'attributo Column. In questo modo specifico che sarà questa la proprietà che definirà il tipo da generare.

    [Column(Storage = "_ContactType", DbType = "TinyInt NOT NULL", IsDiscriminator = true)]
    public byte ContactType

    Successivamente applico i seguenti attributi al tipo Rubrica:

    [Table(Name = "dbo.Rubrica")]
    [
    InheritanceMapping(Code = TipoContatto.Rubrica, Type = typeof(Rubrica), IsDefault = true)]
    [
    InheritanceMapping(Code = TipoContatto.Cliente, Type = typeof(Cliente))]
    [
    InheritanceMapping(Code = TipoContatto.Fornitore, Type = typeof(Fornitore))]
    [
    InheritanceMapping(Code = TipoContatto.Azienda, Type = typeof(Azienda))]
    public partial class Rubrica

    L'attributo InheritanceMapping determina quale sia il valore del campo per cui mi verrà generato uno specifico tipo. Nel primo attributo abbiamo anche impostato quale sia il valore di default (nel caso che il ContentType no nricadesse in nessuno dei valori esplicitati).

    Avrete notato che a fronte di un ContentType numerico sto utilizzando un enum per specificare i vari casi, la scelta è stata fatta solo per aumentare la leggibilità , è bastato definire l'enum TipoContatto come segue:

    public enum TipoContatto : byte
    {
         Rubrica = 0,
         Cliente = 1,
         Fornitore = 2,
         Azienda = 3,
    }

    Fatto questo il motore di Linq to Sql interpreterà il valore del parametro discriminante e restituirà gli oggetti corretti. All'interno di ciascun oggetto potremo apportare le modifiche volute e dei metodi specifici per ciascuna entità.

    Nell'esempio allegato trovate un'implementazione che utilizza un campo CodiceUnivoco per inserire, a seconda del caso, il codice fiscale o la partita iva. Avrei potuto allo stesso modo inseire dei validatori differenti per i due casi. Nello zip trovate anche la query per generare la tabella del database se volete fare una prova completa.

dotNet Umbria 2007-2008
Powered by Community Server (Commercial Edition), by Telligent Systems