Entity framework relations

7 downloads 307 Views 861KB Size Report
Sep 25, 2012 - ARTEC. ENTITY FRAMEWORK RELATIONS ... public class PopularCity. { public int CityID ... tracking features
9/25/2012

ARTEC

ENTITY FRAMEWORK RELATIONS

Relations and Multiplicity in EF 4 | Vahid Hassani http://developerr.blogfa.com

Configuring Multiplicity with the Fluent API Pattern:

Entity.Has[Multiplicity](Property) .With[Multiplicity](Property)

The multiplicity can be: 

Optional (a property that can have a single instance or be  Required (a property that MUST have a single instance)  Many (a property with a collection of a single type)

null)

One to one relationship(1:1 or 1:0) public class City { public int CityID { get; set; } public string Name { get; set; } public virtual PopularCity PopularCity { get; set; }

} public class PopularCity { public int CityID { get; set; } public int Degree { get; set; } public virtual City City { get; set; } } Fluent API:

// Configure the primary key for the PopularCity modelBuilder.Entity() .HasKey(pc => pc.CityID); // Map one-to-zero or one relationship modelBuilder.Entity() .HasRequired(p => p.City) .WithOptional(c => c.PopularCity);

Virtual Lazy Loading: Any virtual ICollections will be lazy-

loaded unless you specifically mark them otherwise.

If you opt to never use the lazy loading or change tracking features of the Entity Framework (which is not the default) then you needn't declare any of your navigation properties as virtual.

Note:

EF infer which type is the dependent and which is the principal

However, when both ends of the relationship are required or both sides are optional the Entity Framework cannot identify the dependent and principal. When both ends of the relationship are required, use WithRequiredPrincipal or WithRequiredDependent after the HasRequired method. When both ends of the relationship are optional, use WithOptionalPrincipal or WithOptionalDependent after the HasOptional method.

// Map one-to-zero or one relationship odelBuilder.Entity() .HasRequired(p => p.City) .WithRequiredPrincipal(c => c.PopularCity);

By Deleting below lines:

// Configure the primary key for the PopularCity modelBuilder.Entity() .HasKey(pc => pc.CityID);

public class City { public int Code { get; set; } public string Name { get; set; }

public class PopularCity { public int Code { get; set; } public int Degree { get; set; }

public virtual PopularCity PopularCity { get; set; } }

public virtual City City { get; set; } }

modelBuilder.Entity() .HasRequired(p => p.City)

.WithOptional(c => c.PopularCity);

modelBuilder.Entity() .HasRequired(p => p.City)

.WithRequiredPrincipal(c => c.PopularCity);

Inheritance Table Per Hierarchy ( TPH ): default inheritance model (Store all data in one table)

public class City { public int ID { get; set; } public string Name { get; set; } } public class PopularCity:City { public int Degree { get; set; } }

Table Per Type ( TPT ): public class City { public int ID { get; set; } public string Name { get; set; } } [Table("PopularCities")] public class PopularCity:City { public int Degree { get; set; } }

TPT (Fluent API) public class City { public int ID { get; set; } public string Name { get; set; } } public class PopularCity:City { public int Degree { get; set; } } modelBuilder.Entity() .ToTable("PopularCities");

Note:Result is the same.

One to Many relationship(1:N) public class City { public int ID { get; set; } public string Name { get; set; } } public class Person { public int ID{ get; set; } public string Name { get; set; } public DateTime BirthDay { get; set; } public int city_id { get; set; } }

public class Person { public int ID{ get; set; } public string Name { get; set; } public DateTime BirthDay { get; set; } public City City { get; set; } }

public class Person { public int ID{ get; set; } public string Name { get; set; } public DateTime BirthDay { get; set; } public int CityId { get; set; } public City City { get; set; } }

public class City { public int ID { get; set; } public string Name { get; set; } public ICollection People { get; set; } } public class Person { public int ID { get; set; } public string Name { get; set; } public DateTime BirthDay { get; set; } }

public class Person { public int ID { get; set; } public string Name { get; set; } public DateTime BirthDay { get; set; } public int CityId { get; set; } }

Annotations(cascading delete) public class City { public int ID { get; set; } public string Name { get; set; } } public class Person { public int ID { get; set; } public string Name { get; set; } public DateTime BirthDay { get; set; } [Required] public City City { get; set; } }

If you want to have the relationship optional but WITH cascading delete:

public class City { public int ID { get; set; } public string Name { get; set; } } public class Person { public int ID { get; set; } public string Name { get; set; } public DateTime BirthDay { get; set; } public City City { get; set; } }

Fluent API:

modelBuilder.Entity() .HasOptional(p => p.City) .WithMany() .WillCascadeOnDelete();

Note 1:

public class City { public int ID { get; set; } public string Name { get; set; } } public class Person { public int ID{ get; set; } public string Name { get; set; } public DateTime BirthDay { get; set; } public City City { get; set; } }

City_ID is added automatically

Example: public class City { public int ID { get; set; } public string Name { get; set; } } public class Habit { public int ID { get; set; } public string Name { get; set; } } public class Person { public int ID{ get; set; } public string Name { get; set; } public DateTime BirthDay { get; set; } public int CityId { get; set; } public City City { get; set; } public ICollection Habits { get; set; } }

Many To Many Relation In EF 4.1 CTP5 cascading delete is enabled automatically for many to many relationships.

public class User { public int UserId { get; set; } public string UserName { get; set; } public string Password { get; set; } public ICollection Roles { get; set; } } public class Role { public int RoleId { get; set; } public string Name { get; set; } public ICollection Users { get; set; } }

ALTER TABLE [RoleUsers] ADD CONSTRAINT [FK_RoleUsers_Roles_Role_RoleId] FOREIGN KEY ([Role_RoleId]) REFERENCES [Roles] ([RoleId]) ON DELETE CASCADE

ALTER TABLE [RoleUsers] ADD CONSTRAINT [FK_RoleUsers_Users_User_UserId] FOREIGN KEY ([User_UserId]) REFERENCES [Users] ([UserId]) ON DELETE CASCADE

modelBuilder.Entity() .HasMany(r => r.Users) .WithOptional();

Both relations are No Action on Delete

modelBuilder.Entity() .HasMany(r => r.Users) .WithMany(u => u.Roles) .Map(t => t.ToTable("UsersRoles"));

Both Relations are Cascade Delete

modelBuilder.Entity() .HasMany(r => r.Users) .WithMany(u => u.Roles) .Map(t => { t.MapLeftKey("rid"); t.MapRightKey("uid"); t.ToTable("UsersRoles"); } );

Self Reference public class Person { public int ID { get; set; } public string Name { get; set; } public DateTime BirthDay { get; set; } public Person Father { get; set; } }

public class Person { public int ID { get; set; } public string Name { get; set; } public DateTime BirthDay { get; set; } public ICollection Brothers { get; set; } }

modelBuilder.Entity() .HasMany(p => p.Brothers) .WithMany() .Map(t => t.ToTable("Brothers"));

Mapped the Brotherhood relation to Brothers table.

Suggest Documents