Saturday 12 July 2014

Life Cycle of Entity

During entity’s lifetime, each entity has an entity state based on operation performed on it via Context (ObjectContext). The entity state is an enum of type System.Data.EntityState that declares the following values:


  1. Added
  2. Deleted
  3. Modified
  4. Unchanged
  5. Detached


The Context not only holds the reference to all the objects retrieved from the database but also it holds the entity states and maintains modifications to the properties of the entity. This feature is known as Change Tracking.
The change in entity state from the Unchanged to the Modified state is the only state that’s automatically handled by the context. All other changes must be made explicitly using proper methods of ObjectContext:


Sr.
ObjectContext Methods
Description
EntityState
1
AddObject
Adds an entity to the context
Added
2
Attach
Attaches an entity to the context
Unchanged
3
ApplyCurrentValues
Replace currently attached entity’s scalar value with the property values of detached entity.
Modified
4
ApplyOriginalValues
It applies original database values to attached entity’s properties.
Unchanged
5
DeleteObject
Delete the object from context.
Deleted
6
AcceptAllChanges
pushes the current values of every attached entity into the original values.
Unchanged
7
ChangeState or ChangeObjectState
Change an entity from one state to another without any restrictions (except for Detached)
Based on passed state
8
Detach
Removes an entity from the context.
Detached

Type Of Entity

There are four types of Entities in Entity Framework 4.x, 1) EntityObject 2) POCO 3) POCO Proxy 4) Self-Tracking Entities.

EntityObject: By default, the ADO.NET Entity Data Model tools generate EntityObject derived entities. If you check entities created in previous step, it is of this type. When you work with EntityObject derived types, the object context manages the relationships between your objects, tracks changes as they occur, and supports lazy loading in the most efficient manner. However, the EntityObject derived types have strong dependency on the Entity Framework. If you are working with architectures that require persistence ignorance (for example, test- driven development or domain-driven development) or you have existing domain classes, consider using POCO or POCO proxies.
Following is an example of auto generated Student entity which is derived from EntityObject class:

[EdmEntityTypeAttribute(NamespaceName="SchoolDBModel", Name="Student")]
   [Serializable()]
   [DataContractAttribute(IsReference=true)]
   public partial class Student : EntityObject
   {
       #region Factory Method
   
       /// <summary>
       /// Create a new Student object.
       /// </summary>
       /// <param name="studentID">Initial value of the StudentID property.</param>
       /// <param name="standardId">Initial value of the StandardId property.</param>
       public static Student CreateStudent(global::System.Int32 studentID, global::System.Int32 standardId)
       {
           Student student = new Student();
           student.StudentID = studentID;
           student.StandardId = standardId;
           return student;
       }

       #endregion
       #region Primitive Properties
   
       /// <summary>
       /// No Metadata Documentation available.
       /// </summary>
       [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
       [DataMemberAttribute()]
       public global::System.Int32 StudentID
       {
           get
           {
               return _StudentID;
           }
           set
           {
               if (_StudentID != value)
               {
                   OnStudentIDChanging(value);
                   ReportPropertyChanging("StudentID");
                   _StudentID = StructuralObject.SetValidValue(value);
                   ReportPropertyChanged("StudentID");
                   OnStudentIDChanged();
               }
           }
       }
       private global::System.Int32 _StudentID;
       partial void OnStudentIDChanging(global::System.Int32 value);
       partial void OnStudentIDChanged();
   
       /// <summary>
       /// No Metadata Documentation available.
       /// </summary>
       [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
       [DataMemberAttribute()]
       public global::System.String StudentName
       {
           get
           {
               return _StudentName;
           }
           set
           {
               OnStudentNameChanging(value);
               ReportPropertyChanging("StudentName");
               _StudentName = StructuralObject.SetValidValue(value, true);
               ReportPropertyChanged("StudentName");
               OnStudentNameChanged();
           }
       }
       private global::System.String _StudentName;
       partial void OnStudentNameChanging(global::System.String value);
       partial void OnStudentNameChanged();
   
       /// <summary>
       /// No Metadata Documentation available.
       /// </summary>
       [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
       [DataMemberAttribute()]
       public global::System.Int32 StandardId
       {
           get
           {
               return _StandardId;
           }
           set
           {
               OnStandardIdChanging(value);
               ReportPropertyChanging("StandardId");
               _StandardId = StructuralObject.SetValidValue(value);
               ReportPropertyChanged("StandardId");
               OnStandardIdChanged();
           }
       }
       private global::System.Int32 _StandardId;
       partial void OnStandardIdChanging(global::System.Int32 value);
       partial void OnStandardIdChanged();

       #endregion
   
       #region Navigation Properties
   
       /// <summary>
       /// No Metadata Documentation available.
       /// </summary>
       [XmlIgnoreAttribute()]
       [SoapIgnoreAttribute()]
       [DataMemberAttribute()]
       [EdmRelationshipNavigationPropertyAttribute("SchoolDBModel", "FK_Student_Standard", "Standard")]
       public Standard Standard
       {
           get
           {
               return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Standard>("SchoolDBModel.FK_Student_Standard", "Standard").Value;
           }
           set
           {
               ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Standard>("SchoolDBModel.FK_Student_Standard", "Standard").Value = value;
           }
       }
       /// <summary>
       /// No Metadata Documentation available.
       /// </summary>
       [BrowsableAttribute(false)]
       [DataMemberAttribute()]
       public EntityReference<Standard> StandardReference
       {
           get
           {
               return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<Standard>("SchoolDBModel.FK_Student_Standard", "Standard");
           }
           set
           {
               if ((value != null))
               {
                   ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<Standard>("SchoolDBModel.FK_Student_Standard", "Standard", value);
               }
           }
       }
   
       /// <summary>
       /// No Metadata Documentation available.
       /// </summary>
       [XmlIgnoreAttribute()]
       [SoapIgnoreAttribute()]
       [DataMemberAttribute()]
       [EdmRelationshipNavigationPropertyAttribute("SchoolDBModel", "FK_StudentAddress_Student", "StudentAddress")]
       public StudentAddress StudentAddress
       {
           get
           {
               return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<StudentAddress>("SchoolDBModel.FK_StudentAddress_Student", "StudentAddress").Value;
           }
           set
           {
               ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<StudentAddress>("SchoolDBModel.FK_StudentAddress_Student", "StudentAddress").Value = value;
           }
       }
       /// <summary>
       /// No Metadata Documentation available.
       /// </summary>
       [BrowsableAttribute(false)]
       [DataMemberAttribute()]
       public EntityReference<StudentAddress> StudentAddressReference
       {
           get
           {
               return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<StudentAddress>("SchoolDBModel.FK_StudentAddress_Student", "StudentAddress");
           }
           set
           {
               if ((value != null))
               {
                   ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<StudentAddress>("SchoolDBModel.FK_StudentAddress_Student", "StudentAddress", value);
               }
           }
       }
   
       /// <summary>
       /// No Metadata Documentation available.
       /// </summary>
       [XmlIgnoreAttribute()]
       [SoapIgnoreAttribute()]
       [DataMemberAttribute()]
       [EdmRelationshipNavigationPropertyAttribute("SchoolDBModel", "StudentCourse", "Course")]
       public EntityCollection<Course> Courses
       {
           get
           {
               return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Course>("SchoolDBModel.StudentCourse", "Course");
           }
           set
           {
               if ((value != null))
               {
                   ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Course>("SchoolDBModel.StudentCourse", "Course", value);
               }
           }
       }

       #endregion
   }


POCO (Plain Old CLR Object): POCO class is the class which doesn’t depend on any framework specific base class. It is like any other normal .net class that is why it is called “Plain Old CLR Objects”. The Entity Framework 4.1 enables you to use existing .net classes together with the data model without making any modifications to the existing .net classes. These POCO entities (also known as persistence-ignorant objects) support most of the same LINQ queries as EntityObject derived entities .
Following is a Student POCO class:

public class Student
   {
       public int StudentID { get; set; }

       public string StudentName{ get; set; }

       public Standard Standard{ get ; set; }

       public StudentAddress StudentAddress{ get ; set; }

       public IList<Course> Courses{ get; set; }

   }

POCO Proxy: POCO Proxy is a runtime proxy class of POCO entity. POCO entity becomes POCO Proxy entity if it meets certain requirements to enable lazy loading proxy and instant change tracking. It adds some methods at runtime to your POCO class which does instant change tracking and lazy loading stuff.
POCO entity should meet the following requirement to become POCO proxy:
  1. A custom data class must be declared with public access.
  2. A custom data class must not be sealed (NotInheritable in Visual Basic)
  3. A custom data class must not be abstract (MustInherit in Visual Basic).
  4. A custom data class must have a public or protected constructor that does not have parameters.
  5. The class cannot implement the IEntityWithChangeTracker or IEntityWithRelationships interfaces because the proxy classes implement these interfaces.
  6. The ProxyCreationEnabled option must be set to true.
  7. Each navigation property must be declared as public, virtual

public class Student
   {
       public virtual int StudentID { get; set; }

       public virtual string StudentName { get; set; }

       public virtual Standard Standard { get; set; }

       public virtual StudentAddress StudentAddress { get; set; }

       public virtual IList<Course> Courses { get; set; }

   }

Self-Tracking Entities: The EntityObject derived entities, POCO, and POCO proxy entities works well in 

Architecture of Entity Framework



EDM (Entity Data Model): EDM consist three main parts- Conceptual model, Mapping and Storage model.

Conceptual Model: Conceptual model is your model classes and their relationships. This will be independent from your database table design.

Storage Model: Storage model is your database design model which includes tables, views, stored procedures and their relationships and keys.

Mapping: Mapping consist information about how your conceptual model is mapped to storage model.

LINQ to Entities:LINQ to Entities is query language used to write queries against the object model. It returns entities which are defined in the conceptual model. You can use your LINQ skills here.

Entity SQL:Entity SQL is again a query language same as LINQ to Entities. However it is little more difficult than L2E and also developer need to learn it separately.

Object Service:Object service is a main entry point for accessing data from database and to return it back. Object service is responsible for materialization which is process of converting data returned from entity client data provider (next layer) to an entity object structure.

Entity Client Data Provider:The main responsibility of this layer is to convert L2E or Entity SQL queries into SQL query which is understood by underlying database. It communicates with ADO.Net data provider which in turn sends or retrieves data from database.

ADO.Net Data Provider:This layer communicates with database using standard ADO.Net.

Introduction of Entity Framework

1. Version

    - 3.5
    - 4
    - 4.1
    - 4.1.1
    - 4.2
    - 4.3
    - 4.3.1
    - 4.5
    - 4.6 

2. What is Entity Framework.

So let’s see standard definition of Entity Framework given by Microsoft:

The Microsoft ADO.NET Entity Framework is an Object/Relational Mapping (ORM) framework that enables developers to work with relational data as domain-specific objects, eliminating the need for most of the data access plumbing code that developers usually need to write. Using the Entity Framework, developers issue queries using LINQ, then retrieve and manipulate data as strongly typed objects. The Entity Framework’s ORM implementation provides services like change tracking, identity resolution, lazy loading, and query translation so that developers can focus on their application-specific business logic rather than the data access fundamentals.

To simply say it: Entity framework is an Object/Relational Mapping (O/RM) framework. It is an enhancement to ADO.NET that gives developers an automated mechanism for accessing & storing the data in the database and working with the results in addition to DataReader and DataSet.

Benefits:

1. Applications can work in terms of a more application-centric conceptual model, including types with inheritance, complex members, and relationships.
2. Applications are freed from hard-coded dependencies on a particular data engine or storage schema.
3. Mappings between the conceptual model and the storage-specific schema can change without changing the application code.
4. Developers can work with a consistent application object model that can be mapped to various storage schemas, possibly implemented in different database management systems.
5. Multiple conceptual models can be mapped to a single storage schema.
6. Language-integrated query (LINQ) support provides compile-time syntax validation for queries against a conceptual model.