Usare Entity Framework Code First con Wcf Web Services

In questo articolo vogliamo dimostrare come poter usare le classi DataMember esposte in un WCF come entità per creare un Db Code First con Entity Framework insieme alle Lazy loading.

Prepariamo due classi di Test.

DataContract(IsReference=true)]
public class Account 
{
    protected Account() { }

    [DataMember]
    public int ID { get; set; }

    [DataMember]
    public string Username { get; set; }

    public string Password { get; set; }

    [DataMember]
    public virtual int PersonID { get; set; }
    [DataMember]
    public virtual Person Person { get; set; }
}

[DataContract(IsReference = true)] 
public class Person
{
    protected Person() { }

    [DataMember]
    public int ID { get; set; }

    [DataMember]
    public string Firstname { get; set; }
    [DataMember]
    public string Lastname { get; set; }

    [DataMember]
    public virtual ICollection<Account> Accounts { get; set; }
}

Utilizziamo IsReference=true per evitare ricorsioni indefiniti durante la serializzazione.

Ora sviluppiamo la classe che eredita dal DbContext per creare il Db come CodeFirst. Nel costruttore inseriamo la classe proxy e usiamo il lazy loading.

public class DataContext : DbContext
{
    public DataContext()
    {
        Configuration.AutoDetectChangesEnabled = true;
        Configuration.LazyLoadingEnabled = true;
        Configuration.ProxyCreationEnabled = true;
        Configuration.ValidateOnSaveEnabled = true;
    }

    protected override void Dispose(bool disposing)
    {
        Configuration.LazyLoadingEnabled = false; 
        base.Dispose(disposing);
    }

    public DbSet<Account> Accounts { get; set; }
    public DbSet<Person> Persons { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Account>()
                    .Property(s => s.Username)
                    .IsRequired();

        modelBuilder.Entity<Account>()
                    .HasRequired(p => p.Person)
                    .WithMany(p => p.Accounts)
                    .HasForeignKey(p => p.PersonID)
                    .WillCascadeOnDelete(true);
    }

Nel metodo Dispose disabiliamo il lazy loading, altrimenti riceveremo un errore dal serializzatore del Wcf.

Il prossimo frammento di codice mostra i metodi del servizio. Oltre all’attributo OperationContract che serve per esporre il metodo, abbiamo aggiunto un nuovo attributo ApplyDataContractResolver, la classe è scaricabile qui. Questo attributo è necessario per trasformare l’oggetto Entity Framework in POCO object.

[ServiceContract]
public class MyService
{
    [OperationContract]
    [ApplyDataContractResolver]
    public Account GetAccount(string username)
    {
        using (var ctx = new DataContext())
        {
            return ctx.Accounts.
                Include("Person").
                SingleOrDefault(a => a.Username == username).ToList();
        }
    }

    [OperationContract]
    [ApplyDataContractResolver]
    public IList<Person> GetAllPersons()
    {
        using (var ctx = new DataContext())
            return ctx.Persons.Include("Accounts").ToList();
    }
}
Annunci

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...