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:
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")