420 likes | 640 Views
LINQ Boot Camp. ADO.Net Entity Framework. Presenter :. Mah esh Moily. Date :. Nov 26, 2009. Agenda. ADO.Net Entity Framework Need of ADO.Net Entity Framework The Entity Data Model Object Services CUD Operations Concurrency Control Transaction Control. ADO.Net Entity Framework.
E N D
LINQ Boot Camp ADO.Net Entity Framework Presenter: Mahesh Moily Date: Nov 26, 2009
Agenda • ADO.Net Entity Framework • Need of ADO.Net Entity Framework • The Entity Data Model • Object Services • CUD Operations • Concurrency Control • Transaction Control
ADO.Net Entity Framework • ADO.NET Entity Framework is an object-relational mapping (ORM) framework for the .NET Framework. • ADO.Net Entity Framework and Linq raises the level of abstraction for data programming. • Helps to eliminate the impedance mismatch between data models and between languages.
Why do we need ADO.Net Entity Framework? • Currently most applications are written on top of relational databases. • This requires understanding of database and involves complex data access code. • ADO.Net Entity Framework helps isolate the application from the underlying logical database schemas. • Enables programming against a conceptual application model instead of programming directly against a relational storage schema. • Developers can work with a consistent application object model that can be mapped to various storage schemas.
Why do we need ADO.Net Entity Framework? • The below ER model is the way currently data is stored in a relational database. • In the above approach, to retrieve the project name and the country of the employee named “Bob” we will need a three way join targeted to the relational structure. SELECT p.ProjectName, a.Country FROM Project p INNER JOIN Employee e ON p. EmployeeID = e.EmployeeID INNER JOIN Address a ON e.EmployeeID = a. EmployeeID WHERE e.FirstName = “Bob”
Why do we need ADO.Net Entity Framework? • The below conceptual model is the goal for ADO. Net Entity Framework. • In the above approach, to retrieve the project name and the country of the employee named “Bob” we will target the conceptual model and work with entities. objectContext.Employee.Where("it.FirstName = 'Bob'").First().Address.First().Country objectContext.Employee.Where("it.FirstName = ‘Bob'").First().Project.First().ProjectName
The Entity Data Model • The Entity Data Model (EDM) is a ER data model which describe the data structure (schema) using high level constructs. • This model represents application data as a set of entities and relationships that are mapped to a defined data source. • An EDM consists • The Conceptual Model • The Storage Model • The Mapping Specification
The Conceptual Model • The conceptual model is an Entity Data Model (EDM) schema that defines the entities and associations in the EDM. • The XML syntax that defines this model is called the conceptual schema definition language (CSDL).
The Conceptual Model - CSDL <edmx:ConceptualModels> <Schema Namespace="CompanyModel" Alias="Self"> <EntityContainer Name="CompanyEntities1“> </EntityContainer> <EntityType Name="Address“> </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee“> </Association> </Schema> </edmx:ConceptualModels>
The Conceptual Model - CSDL <edmx:ConceptualModels> <Schema Namespace="CompanyModel" Alias="Self"> <EntityContainer Name="CompanyEntities1"> <EntitySet Name="Address" EntityType="CompanyModel.Address" /> <EntitySet Name="Employee" EntityType="CompanyModel.Employee" /> ... <AssociationSet Name="FK_Address_Employee" Association="CompanyModel.FK_Address_Employee"> <End Role="Employee" EntitySet="Employee" /> <End Role="Address" EntitySet="Address" /> </AssociationSet> ... </EntityContainer> <EntityType Name="Address“> </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee“> </Association> </Schema> </edmx:ConceptualModels>
The Conceptual Model - CSDL <edmx:ConceptualModels> <Schema Namespace="CompanyModel" Alias="Self"> <EntityContainer Name="CompanyEntities1“> </EntityContainer> <EntityType Name="Address“> </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee“> </Association> </Schema> </edmx:ConceptualModels>
The Conceptual Model - CSDL <edmx:ConceptualModels> <Schema Namespace="CompanyModel" Alias="Self"> <EntityContainer Name="CompanyEntities1“> </EntityContainer> <EntityType Name="Address"> <Key> <PropertyRef Name="AddressID" /> </Key> <Property Name="AddressID" Type="Int32" Nullable="false" /> <Property Name="Address1" Type="String" MaxLength="50" Unicode="true" FixedLength="false" ConcurrencyMode="Fixed" /> <NavigationProperty Name="Employee" Relationship="CompanyModel.FK_Address_Employee" FromRole="Address" ToRole="Employee" /> </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee“> </Association> </Schema> </edmx:ConceptualModels>
The Conceptual Model - CSDL <edmx:ConceptualModels> <Schema Namespace="CompanyModel" Alias="Self"> <EntityContainer Name="CompanyEntities1“> </EntityContainer> <EntityType Name="Address“> </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee“> </Association> </Schema> </edmx:ConceptualModels>
The Conceptual Model - CSDL <edmx:ConceptualModels> <Schema Namespace="CompanyModel" Alias="Self"> <EntityContainer Name="CompanyEntities1“> </EntityContainer> <EntityType Name="Address“> </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee"> <End Role="Employee" Type="CompanyModel.Employee" Multiplicity="0..1" /> <End Role="Address" Type="CompanyModel.Address" Multiplicity="*" /> </Association> </Schema> </edmx:ConceptualModels>
The Storage Model • The storage model is an Entity Data Model (EDM) schema that defines the logical structure of persistent data, usually stored in a relational database. • The XML syntax that defines this model is called the store schema definition language (SSDL) .
The Storage Model - SSDL <edmx:StorageModels> <Schema Namespace="CompanyModel.Store" Alias="Self" Provider="System.Data.SqlClient"> <EntityContainer Name="CompanyModelStoreContainer"> </EntityContainer> <EntityType Name="Address“> </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee“> </Association> </Schema> </ edmx:StorageModels >
The Storage Model - SSDL <edmx:StorageModels> <Schema Namespace="CompanyModel.Store" Alias="Self" Provider="System.Data.SqlClient"> <EntityContainer Name="CompanyModelStoreContainer"> <EntitySet Name="Address" EntityType="CompanyModel.Store.Address" store:Type="Tables" Schema="dbo" /> <EntitySet Name="Employee" EntityType="CompanyModel.Store.Employee" store:Type="Tables" Schema="dbo" /> <AssociationSet Name="FK_Address_Employee" Association="CompanyModel.Store.FK_Address_Employee"> <End Role="Employee" EntitySet="Employee" /> <End Role="Address" EntitySet="Address" /> </AssociationSet> </EntityContainer> <EntityType Name="Address“> </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee“> </Association> </Schema> </ edmx:StorageModels >
The Storage Model - SSDL <edmx:StorageModels> <Schema Namespace="CompanyModel.Store" Alias="Self" Provider="System.Data.SqlClient"> <EntityContainer Name="CompanyModelStoreContainer"> </EntityContainer> <EntityType Name="Address“> </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee“> </Association> </Schema> </ edmx:StorageModels >
The Storage Model - SSDL <edmx:StorageModels> <Schema Namespace="CompanyModel.Store" Alias="Self" Provider="System.Data.SqlClient"> <EntityContainer Name="CompanyModelStoreContainer"> </EntityContainer> <EntityType Name="Address"> <Key> <PropertyRef Name="AddressID" /> </Key> <Property Name="AddressID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" /> <Property Name="EmployeeID" Type="int" /> <Property Name="Address1" Type="nvarchar" MaxLength="50" /> ... </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee“> </Association> </Schema> </ edmx:StorageModels >
The Storage Model - SSDL <edmx:StorageModels> <Schema Namespace="CompanyModel.Store" Alias="Self" Provider="System.Data.SqlClient"> <EntityContainer Name="CompanyModelStoreContainer"> </EntityContainer> <EntityType Name="Address“> </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee“> </Association> </Schema> </ edmx:StorageModels >
The Storage Model - SSDL <edmx:StorageModels> <Schema Namespace="CompanyModel.Store" Alias="Self" Provider="System.Data.SqlClient"> <EntityContainer Name="CompanyModelStoreContainer"> </EntityContainer> <EntityType Name="Address“> </EntityType> <EntityType Name=“Employee“> </EntityType> <Association Name="FK_Address_Employee"> <End Role="Employee" Type="CompanyModel.Store.Employee" Multiplicity="0..1" /> <End Role="Address" Type="CompanyModel.Store.Address" Multiplicity="*" /> <ReferentialConstraint> <Principal Role="Employee"> <PropertyRef Name="EmployeeID" /> </Principal> <Dependent Role="Address"> <PropertyRef Name="EmployeeID" /> </Dependent> </ReferentialConstraint> </Association> </Schema> </ edmx:StorageModels >
The Mapping Specification • The mapping specification is an Entity Data Model (EDM) schema that defines the connection between the types declared in conceptual model and the database metadata declared in storage model. • The XML syntax that defines this model is called the mapping specification language (MSL) .
The Mapping Specification - MSL <edmx:Mappings> <Mapping Space="C-S"> <EntityContainerMapping StorageEntityContainer="CompanyModelStoreContainer" CdmEntityContainer="CompanyEntities1"> <EntitySetMapping Name="Address"> </EntitySetMapping> <EntitySetMapping Name="Employee"> </EntitySetMapping> <AssociationSetMapping Name="FK_Address_Employee" TypeName="CompanyModel.FK_Address_Employee" StoreEntitySet="Address"> </EntityContainerMapping> </Mapping> </edmx:Mappings>
The Mapping Specification - MSL <edmx:Mappings> <Mapping Space="C-S"> <EntityContainerMapping StorageEntityContainer="CompanyModelStoreContainer" CdmEntityContainer="CompanyEntities1"> <EntitySetMapping Name="Address"> <EntityTypeMapping TypeName="IsTypeOf(CompanyModel.Address)"> <MappingFragment StoreEntitySet="Address"> <ScalarProperty Name="AddressID" ColumnName="AddressID" /> <ScalarProperty Name="Address1" ColumnName="Address1" /> </MappingFragment> </EntityTypeMapping> </EntitySetMapping> <EntitySetMapping Name="Employee"> </EntitySetMapping> <AssociationSetMapping Name="FK_Address_Employee" TypeName="CompanyModel.FK_Address_Employee" StoreEntitySet="Address"> </EntityContainerMapping> </Mapping> </edmx:Mappings>
The Mapping Specification - MSL <edmx:Mappings> <Mapping Space="C-S"> <EntityContainerMapping StorageEntityContainer="CompanyModelStoreContainer" CdmEntityContainer="CompanyEntities1"> <EntitySetMapping Name="Address"> </EntitySetMapping> <EntitySetMapping Name="Employee"> </EntitySetMapping> <AssociationSetMapping Name="FK_Address_Employee" TypeName="CompanyModel.FK_Address_Employee" StoreEntitySet="Address"> </EntityContainerMapping> </Mapping> </edmx:Mappings>
The Mapping Specification - MSL <edmx:Mappings> <Mapping Space="C-S"> <EntityContainerMapping StorageEntityContainer="CompanyModelStoreContainer" CdmEntityContainer="CompanyEntities1"> <EntitySetMapping Name="Address"> </EntitySetMapping> <EntitySetMapping Name="Employee"> </EntitySetMapping> <AssociationSetMapping Name="FK_Address_Employee" TypeName="CompanyModel.FK_Address_Employee" StoreEntitySet="Address"> <EndProperty Name="Employee"> <ScalarProperty Name="EmployeeID" ColumnName="EmployeeID" /> </EndProperty> <EndProperty Name="Address"> <ScalarProperty Name="AddressID" ColumnName="AddressID" /> </EndProperty> <Condition ColumnName="EmployeeID" IsNull="false" /> </AssociationSetMapping> </EntityContainerMapping> </Mapping> </edmx:Mappings>
Object Services • Object services is a layer that enables to query, insert, update and delete data expressed as objects. • Object Services supports both Language-Integrated Query (LINQ) and Entity SQL queries against types that are defined in an Entity Data Model (EDM). • Object Services materializes returned data as objects, and propagates object changes back to the data source. • It also provides facilities for tracking changes, binding objects to controls, and handling concurrency. • Following are some objects that performs the above tasks: • Object Context • Object State Manager
Object Context • Provides facilities for querying and working with entity data as objects. • The ObjectContext class is the primary class for interacting with data as objects that are instances of entity types that are defined in an Entity Data Model (EDM). • An instance of the ObjectContext class encapsulates the following: • A connection to the database, in the form of an EntityConnection object. • Metadata that describes the model, in the form of a MetadataWorkspace object. • An ObjectStateManager object that manages objects persisted in the cache.
Object State Manager • Maintains object state and identity management for entity type instances and relationship instances. • ObjectStateManager does the following: • Tracks query results. • Provides logic to merge multiple overlapping query results. • Performs in-memory change tracking when a user inserts, deletes, or modifies objects. • Provides the change set for updates.
CUD Operations • Following are the issues faced while performing CUD operation in n-tier applications: • Entity objects are serialized and detached from object context. • Changes to the detached entities are no longer tracked by object context. • Association of detached entity with others are not tracked.
CUD Operations - Insert • Steps for inserting new object: • Create instance of new Object to be added. • Add the object to the ObjectContext using its AddTo<Entity>() method. • Call SaveChanges() to insert the object. • Sample code would be like:
CUD Operations - Delete • Steps for deleting an object: • Get the original object to be deleted . • Mark the object to be deleted by passing it to the DeleteObjectmethod of ObjectContext. • Call SaveChanges() to delete the object. • Sample code would be like:
CUD Operations - Update • Steps for updating an object: • Change the properties of the entity in the ObjectContext. • Call SaveChanges() to delete the object. • Sample code would be like:
Concurrency Control • The Entity Framework implements an optimistic concurrency model. • Locks are not held on data in the data source. • By default, Object Services saves object changes to the database without checking for concurrency.
Specify Members to be tested for conflicts • For properties that might experience a high degree of concurrency, the entity property should be defined with an attribute of ConcurrencyMode="fixed“. • When this attribute is used, Object Services checks for changes in the database before saving changes to the database. • Any conflicting changes will cause an OptimisticConcurrencyException.
Resolving Concurrency Conflicts • Resolution of this conflict includes discovering which members of the object are in conflict, and then deciding what you want to do about it. • Following are the refresh modes available to resolve the conflicts: • StoreWins: Retaining Database Values • ClientWins: Overwriting Database Values
StoreWins: Retaining Database Values • In case of concurrency conflicts, you can use StoreWins to retain the values found in the database. • In this scenario, a OptimisticConcurrencyException exception is thrown when User1 tries to submit changes, because User2 has in the meantime changed the Assistant and Department columns. • User1 decides to resolve this conflict by having the newer database values overwrite the current values in the object model. • When User1 resolves the conflict by using StoreWins, the result in the database is as follows in the table:
StoreWins: Retaining Database Values • Sample code would be like:
ClientWins: Overwriting Database Values • In case of concurrency conflicts, you can use ClientWins to overwrite database values. • In this scenario, an OptimisticConcurrencyException exception is thrown when User1 tries to submit changes, because User2 has in the meantime changed the Assistant and Department columns. • User1 decides to resolve this conflict by overwriting database values with the current client member values. • When User1 resolves the conflict by using ClientWins, the result in the database is as in following table:
ClientWins: Overwriting Database Values • Sample code would be like:
Transaction Control • Object Services supports automatic transaction enlistment. • The following considerations apply when you use transactions with Object Services: • Only operations against the data source are transacted. Changes made to objects in the object context are not transacted. • When you call SaveChanges(), if a current transaction exists Object Services uses this transaction for operations against the data source. Otherwise, it creates a new transaction for the operation. • When Object Services creates a new transaction for a SaveChanges operation, changes to objects in the object context are not accepted until the transaction completes. This ensures that the state of the object context and the data source are consistent.