mercredi 17 août 2011

Entity Framework: Code-First, Foreign Key One-To-Many

The object of this article is to (try to) illustrate two ways for configuring a one to many relation by using entity framework 4.1. For the need of the sample I use a very small and anecdotic part of the data model of Cegid Business Applications. That is I use code first on an existing database !!! :)

To help understanding differences, I comment code from one version to the other.

Of course you will need a connecion string:




Please note:

  • the activation of MARS

First: by using the Data Annotations

namespace ef {
    class Program {
        static void Main (string[] args) {
             CegidContext cc = new CegidContext();
            foreach ( gThirdParty gtp in (from t in cc.gThirdParties where t.GBusinesses.Count() > 0 select t) ) {
                 Console.WriteLine("{0,-17} : {1}", gtp.T_TIERS, gtp.GBusinesses.Count());
            }
        }
    }

    [Table("AFFAIRE")]
    public class gBusiness {
        [Key]
         public string AFF_AFFAIRE {get; set;}
         public string AFF_LIBELLE { get; set; }
         public string AFF_TIERS { get; set; }
 
        [ForeignKey("AFF_TIERS")]
         public virtual gThirdParty GThirdParty { get; set; }
    }

    [Table("TIERS")]
    public class gThirdParty {
         public gThirdParty () { 
            GBusinesses = new List<gBusiness>();
        }

        [Key]
         public string T_TIERS { get; set; }
         public string T_LIBELLE { get; set; }
         public virtual ICollection<gBusiness> GBusinesses { get; set; }
    }


    /*public class gBusinessConfiguration
        : EntityTypeConfiguration<gBusiness> {
        public gBusinessConfiguration ()
            : base() {
            HasKey(p => p.AFF_AFFAIRE);
            HasRequired(p => p.GThirdParty).WithMany(t => t.GBusinesses).Map(x => x.MapKey("AFF_TIERS")); 
        }
    }

    public class gThirdPartyConfiguration
        : EntityTypeConfiguration<gThirdParty> {
        public gThirdPartyConfiguration ()
            : base() {
            HasKey(p => p.T_TIERS);
        }
    }*/    
    
    public class CegidContext : DbContext {
        public DbSet<gBusiness> gBussinesses { get; set; }
        public DbSet<gThirdParty> gThirdParties { get; set; }

        /*protected override void OnModelCreating (DbModelBuilder modelBuilder) {
            modelBuilder.Configurations.Add(new gBusinessConfiguration());
            modelBuilder.Configurations.Add(new gThirdPartyConfiguration());
            base.OnModelCreating(modelBuilder);
        }*/
    }
}

Second: by using the fluent API

namespace ef { 
    class Program { 
        static void Main (string[] args) {
            CegidContext cc = new CegidContext();
            foreach ( gThirdParty gtp in (from t in cc.gThirdParties where t.GBusinesses.Count() > 0 select t) ) {
                 Console.WriteLine("{0,-17} : {1}", gtp.T_TIERS, gtp.GBusinesses.Count());
            }
        }
    }

    [Table("AFFAIRE")]
    public class gBusiness { 
        //[Key] 
         public string AFF_AFFAIRE {get; set;} 
         public string AFF_LIBELLE { get; set; } 
         //public string AFF_TIERS { get; set; } 
              
        //[ForeignKey("AFF_TIERS")] 
         public virtual gThirdParty GThirdParty { get; set; } 
    }

    [Table("TIERS")] 
     public class gThirdParty { 
         public gThirdParty () { 
            GBusinesses = new List<gBusiness>(); 
        }

        //[Key] 
         public string T_TIERS { get; set; } 
         public string T_LIBELLE { get; set; } 
         public virtual ICollection<gBusiness> GBusinesses { get; set; } 
    }

    public class gBusinessConfiguration 
       : EntityTypeConfiguration<gBusiness> { 
        public gBusinessConfiguration () 
           : base() { 
           HasKey(p => p.AFF_AFFAIRE); 
           HasRequired(p => p.GThirdParty).
               WithMany(t => t.GBusinesses).
               Map(x => x.MapKey("AFF_TIERS")); 
       } 
    }

    public class gThirdPartyConfiguration 
        : EntityTypeConfiguration<gThirdParty> { 
         public gThirdPartyConfiguration () 
            : base() { 
            HasKey(p => p.T_TIERS); 
        } 
    }

    public class CegidContext : DbContext { 
         public DbSet<gBusiness> gBussinesses { get; set; } 
         public DbSet<gThirdParty> gThirdParties { get; set; }
 
         protected override void OnModelCreating (DbModelBuilder modelBuilder) { 
            modelBuilder.Configurations.Add(new gBusinessConfiguration()); 
            modelBuilder.Configurations.Add(new gThirdPartyConfiguration()); 
            base.OnModelCreating(modelBuilder); 
        } 
    } 
}

Enjoy

Pending question:

  • How to avoid lazy loading and force explicit loading as Linq to SQL allows with DataLoadOption in the DataContext.

Edit -----


About not lazy, here is the way: cc.gThirdParties.Include("GBusinesses")

Aucun commentaire:

Enregistrer un commentaire