entity framework fluent api - relationships

Upload: wivison-silva

Post on 28-Mar-2016

32 views

Category:

Documents


0 download

DESCRIPTION

Documento que descreve o uso de Fluent API. Ótimo guia para desenvolvedores, analistas, arquitetos e engenheiros de software .

TRANSCRIPT

  • 29/04/2015 EntityFrameworkFluentAPIRelationships

    https://msdn.microsoft.com/enus/data/jj591620.aspx 1/4

    Data Developer Center SearchDatawithBing Sign inUnited States English

    Documentation Videos Articles Books Handson Labs Webcasts

    Data Developer Center > Learn > Entity Framework > Get Started > Fluent API Relationships

    Note: This page provides information about setting up relationships in your Code First model using the fluent API. For general information about relationships in EFand how to access and manipulate data using relationships, see Relationships & Navigation Properties.

    When working with Code First, you define your model by defining your domain CLR classes. By default, the Entity Framework uses the Code First conventionsto map your classes to the database schema. If you use the Code First naming conventions, in most cases you can rely on Code First to set up relationshipsbetween your tables based on the foreign keys and navigation properties that you define on the classes. If you do not follow the conventions when definingyour classes, or if you want to change the way the conventions work, you can use the fluent API or data annotations to configure your classes so Code Firstcan map the relationships between your tables.

    IntroductionConfiguring a RequiredtoOptional Relationship OnetoZeroorOneConfiguring a Relationship Where Both Ends Are Required OnetoOneConfiguring a ManytoMany RelationshipConfiguring a Relationship with One Navigation PropertyEnabling Cascade DeleteConfiguring a Composite Foreign KeyRenaming a Foreign Key That Is Not Defined in the ModelConfiguring a Foreign Key Name That Does Not Follow the Code First ConventionModel Used in Samples

    When configuring a relationship with the fluent API, you start with the EntityTypeConfiguration instance and then use the HasRequired, HasOptional, orHasMany method to specify the type of relationship this entity participates in. The HasRequired and HasOptional methods take a lambda expression thatrepresents a reference navigation property. The HasMany method takes a lambda expression that represents a collection navigation property. You can thenconfigure an inverse navigation property by using the WithRequired, WithOptional, and WithMany methods. These methods have overloads that do not takearguments and can be used to specify cardinality with unidirectional navigations.

    You can then configure foreign key properties by using the HasForeignKey method. This method takes a lambda expression that represents the property tobe used as the foreign key.

    The following example configures a onetozeroorone relationship. The OfficeAssignment has the InstructorID property that is a primary key and a foreignkey, because the name of the property does not follow the convention the HasKey method is used to configure the primary key.

    //ConfiguretheprimarykeyfortheOfficeAssignmentmodelBuilder.Entity().HasKey(t=>t.InstructorID)//MaponetozerooronerelationshipmodelBuilder.Entity().HasRequired(t=>t.Instructor).WithOptional(t=>t.OfficeAssignment)

    In most cases the Entity Framework can infer which type is the dependent and which is the principal in a relationship. However, when both ends of therelationship are required or both sides are optional the Entity Framework cannot identify the dependent and principal. When both ends of the relationship arerequired, use WithRequiredPrincipal or WithRequiredDependent after the HasRequired method. When both ends of the relationship are optional, useWithOptionalPrincipal or WithOptionalDependent after the HasOptional method.

    //ConfiguretheprimarykeyfortheOfficeAssignmentmodelBuilder.Entity().HasKey(t=>t.InstructorID)modelBuilder.Entity().HasRequired(t=>t.OfficeAssignment).WithRequiredPrincipal(t=>t.Instructor)

    Home Library Learn Downloads Support Community Forums

    Configuring Relationships with the Fluent API

    Contents

    Introduction

    Configuring a Required-to-Optional Relationship (One-toZero-or-One)

    Configuring a Relationship Where Both Ends Are Required (One-to-One)

  • 29/04/2015 EntityFrameworkFluentAPIRelationships

    https://msdn.microsoft.com/enus/data/jj591620.aspx 2/4

    The following code configures a manytomany relationship between the Course and Instructor types. In the following example, the default Code Firstconventions are used to create a join table. As a result the CourseInstructor table is created with Course_CourseID and Instructor_InstructorID columns.

    modelBuilder.Entity().HasMany(t=>t.Instructors).WithMany(t=>t.Courses)

    If you want to specify the join table name and the names of the columns in the table you need to do additional configuration by using the Map method. Thefollowing code generates the CourseInstructor table with CourseID and InstructorID columns.

    modelBuilder.Entity().HasMany(t=>t.Instructors).WithMany(t=>t.Courses).Map(m=>{m.ToTable("CourseInstructor")m.MapLeftKey("CourseID")m.MapRightKey("InstructorID")})

    A onedirectional also called unidirectional relationship is when a navigation property is defined on only one of the relationship ends and not on both. Byconvention, Code First always interprets a unidirectional relationship as onetomany. For example, if you want a onetoone relationship between Instructorand OfficeAssignment, where you have a navigation property on only the Instructor type, you need to use the fluent API to configure this relationship.

    //ConfiguretheprimaryKeyfortheOfficeAssignmentmodelBuilder.Entity().HasKey(t=>t.InstructorID)modelBuilder.Entity().HasRequired(t=>t.OfficeAssignment).WithRequiredPrincipal()

    You can configure cascade delete on a relationship by using the WillCascadeOnDelete method. If a foreign key on the dependent entity is not nullable, thenCode First sets cascade delete on the relationship. If a foreign key on the dependent entity is nullable, Code First does not set cascade delete on therelationship, and when the principal is deleted the foreign key will be set to null.

    You can remove these cascade delete conventions by using:

    modelBuilder.Conventions.RemovemodelBuilder.Conventions.Remove

    The following code configures the relationship to be required and then disables cascade delete.

    modelBuilder.Entity().HasRequired(t=>t.Department).WithMany(t=>t.Courses).HasForeignKey(d=>d.DepartmentID).WillCascadeOnDelete(false)

    If the primary key on the Department type consisted of DepartmentID and Name properties, you would configure the primary key for the Department and theforeign key on the Course types as follows:

    //CompositeprimarykeymodelBuilder.Entity().HasKey(d=>new{d.DepartmentID,d.Name})//CompositeforeignkeymodelBuilder.Entity()

    Configuring a Many-to-Many Relationship

    Configuring a Relationship with One Navigation Property

    Enabling Cascade Delete

    Configuring a Composite Foreign Key

  • 29/04/2015 EntityFrameworkFluentAPIRelationships

    https://msdn.microsoft.com/enus/data/jj591620.aspx 3/4

    .HasRequired(c=>c.Department).WithMany(d=>d.Courses).HasForeignKey(d=>new{d.DepartmentID,d.DepartmentName})

    If you choose not to define a foreign key on the CLR type, but want to specify what name it should have in the database, do the following:

    modelBuilder.Entity().HasRequired(c=>c.Department).WithMany(t=>t.Courses).Map(m=>m.MapKey("ChangedDepartmentID"))

    If the foreign key property on the Course class was called SomeDepartmentID instead of DepartmentID, you would need to do the following to specify thatyou want SomeDepartmentID to be the foreign key:

    modelBuilder.Entity().HasRequired(c=>c.Department).WithMany(d=>d.Courses).HasForeignKey(c=>c.SomeDepartmentID)

    The following Code First model is used for the samples on this page.

    usingSystem.Data.EntityusingSystem.Data.Entity.ModelConfiguration.Conventions//addareferencetoSystem.ComponentModel.DataAnnotationsDLLusingSystem.ComponentModel.DataAnnotationsusingSystem.Collections.GenericusingSystempublicclassSchoolEntities:DbContext{publicDbSetCourses{getset}publicDbSetDepartments{getset}publicDbSetInstructors{getset}publicDbSetOfficeAssignments{getset}protectedoverridevoidOnModelCreating(DbModelBuildermodelBuilder){//ConfigureCodeFirsttoignorePluralizingTableNameconvention//Ifyoukeepthisconventionthenthegeneratedtableswillhavepluralizednames.modelBuilder.Conventions.Remove()}}publicclassDepartment{publicDepartment(){this.Courses=newHashSet()}//PrimarykeypublicintDepartmentID{getset}publicstringName{getset}publicdecimalBudget{getset}publicSystem.DateTimeStartDate{getset}publicint?Administrator{getset}//NavigationpropertypublicvirtualICollectionCourses{getprivateset}}publicclassCourse{publicCourse(){this.Instructors=newHashSet()}//PrimarykeypublicintCourseID{getset}

    Renaming a Foreign Key That Is Not Defined in the Model

    Configuring a Foreign Key Name That Does Not Follow the Code First Convention

    Model Used in Samples

  • 29/04/2015 EntityFrameworkFluentAPIRelationships

    https://msdn.microsoft.com/enus/data/jj591620.aspx 4/4

    publicstringTitle{getset}publicintCredits{getset}//ForeignkeypublicintDepartmentID{getset}//NavigationpropertiespublicvirtualDepartmentDepartment{getset}publicvirtualICollectionInstructors{getprivateset}}publicpartialclassOnlineCourse:Course{publicstringURL{getset}}publicpartialclassOnsiteCourse:Course{publicOnsiteCourse(){Details=newDetails()}publicDetailsDetails{getset}}publicclassDetails{publicSystem.DateTimeTime{getset}publicstringLocation{getset}publicstringDays{getset}}publicclassInstructor{publicInstructor(){this.Courses=newList()}//PrimarykeypublicintInstructorID{getset}publicstringLastName{getset}publicstringFirstName{getset}publicSystem.DateTimeHireDate{getset}//NavigationpropertiespublicvirtualICollectionCourses{getprivateset}}publicclassOfficeAssignment{//SpecifyingInstructorIDasaprimary[Key()]publicInt32InstructorID{getset}publicstringLocation{getset}//WhentheEntityFrameworkseesTimestampattribute//itconfiguresConcurrencyCheckandDatabaseGeneratedPattern=Computed.[Timestamp]publicByte[]Timestamp{getset}//NavigationpropertypublicvirtualInstructorInstructor{getset}}

    2015 Microsoft. All rights reserved. Terms of Use | Trademarks | Privacy Statement | Site Feedback