Generic Data Access Layer using ADO.NET Entity Framework : Part 2

In this article, we will take a deeper look at what the Entity Framework provides us and how we can modify it to achieve a Generic Data Access Layer.

In Part 1: Generic Data Access Layer using ADO.NET Entity Framework of this series, I demonstrated how to generate a data model using the ADO.NET Entity Framework. 
 
In this article, we will take a deeper look at what the ADO.NET Entity Framework has provided us and how we can modify it to achieve a Generic Data Access Layer.
 
The Entity Framework creates a ObjectContext class for us. This class provides us access to all the tables in the database and hence provides access to the data.
 
The following code snippet is an example of how a DataContext class is created by the ADO.NET Entity Framework.
  1. public partial class PublishingCompanyEntities : ObjectContext  
  2. {  
  3.   
  4. }  
If you dig deeper into this class, you will see definitions like the following:
 
Generic Dal using WCF 
 
As shown in the screenshot above, the ObjectContext provides us with methods which help us access the Database.
 
Now let's take a look at the entities. The Entity Framework creates partial classes for each of the tables in the data model. These partial classes extend the EntityObject class as shown below.
 
Generic Dal using WCF 
 
Below is the code for the Author entity. 
  1. [EdmEntityTypeAttribute(NamespaceName = "PublishingCompanyModel", Name = "Author")]  
  2. [Serializable()]  
  3. [DataContractAttribute(IsReference=true)]  
  4. public partial class Author : EntityObject  
  5. {  
  6.     #region Factory Method  
  7.   
  8.     /// <summary>  
  9.     /// Create a new Author object.  
  10.     /// </summary>  
  11.     /// <param name="authorID">Initial value of the AuthorID property.</param>  
  12.     public static Author CreateAuthor(global::System.Int32 authorID)  
  13.     {  
  14.         Author author = new Author();  
  15.         author.AuthorID = authorID;  
  16.         return author;  
  17.     }  
  18.  
  19.     #endregion  
  20.     #region Primitive Properties  
  21.   
  22.     /// <summary>  
  23.     /// No Metadata Documentation available.  
  24.     /// </summary>  
  25.     [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]  
  26.     [DataMemberAttribute()]  
  27.     public global::System.Int32 AuthorID  
  28.     {  
  29.         get  
  30.         {  
  31.             return _AuthorID;  
  32.         }  
  33.         set  
  34.         {  
  35.             if (_AuthorID != value)  
  36.             {  
  37.                 OnAuthorIDChanging(value);  
  38.                 ReportPropertyChanging("AuthorID");  
  39.                 _AuthorID = StructuralObject.SetValidValue(value);  
  40.                 ReportPropertyChanged("AuthorID");  
  41.                 OnAuthorIDChanged();  
  42.             }  
  43.         }  
  44.     }  
  45.     private global::System.Int32 _AuthorID;  
  46.     partial void OnAuthorIDChanging(global::System.Int32 value);  
  47.     partial void OnAuthorIDChanged();  
  48.   
  49.     /// <summary>  
  50.     /// No Metadata Documentation available.  
  51.     /// </summary>  
  52.     [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]  
  53.     [DataMemberAttribute()]  
  54.     public global::System.String FirstName  
  55.     {  
  56.         get  
  57.         {  
  58.             return _FirstName;  
  59.         }  
  60.         set  
  61.         {  
  62.             OnFirstNameChanging(value);  
  63.             ReportPropertyChanging("FirstName");  
  64.             _FirstName = StructuralObject.SetValidValue(value, true);  
  65.             ReportPropertyChanged("FirstName");  
  66.             OnFirstNameChanged();  
  67.         }  
  68.     }  
  69.     private global::System.String _FirstName;  
  70.     partial void OnFirstNameChanging(global::System.String value);  
  71.     partial void OnFirstNameChanged();  
  72.   
  73.     /// <summary>  
  74.     /// No Metadata Documentation available.  
  75.     /// </summary>  
  76.     [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]  
  77.     [DataMemberAttribute()]  
  78.     public global::System.String LastName  
  79.     {  
  80.         get  
  81.         {  
  82.             return _LastName;  
  83.         }  
  84.         set  
  85.         {  
  86.             OnLastNameChanging(value);  
  87.             ReportPropertyChanging("LastName");  
  88.             _LastName = StructuralObject.SetValidValue(value, true);  
  89.             ReportPropertyChanged("LastName");  
  90.             OnLastNameChanged();  
  91.         }  
  92.     }  
  93.     private global::System.String _LastName;  
  94.     partial void OnLastNameChanging(global::System.String value);  
  95.     partial void OnLastNameChanged();  
  96.  
  97.     #endregion  
  98.  
  99.     #region Navigation Properties  
  100.   
  101.     /// <summary>  
  102.     /// No Metadata Documentation available.  
  103.     /// </summary>  
  104.     [XmlIgnoreAttribute()]  
  105.     [SoapIgnoreAttribute()]  
  106.     [DataMemberAttribute()]  
  107.     [EdmRelationshipNavigationPropertyAttribute("PublishingCompanyModel""FK_Article_Author""Article")]  
  108.     public EntityCollection<Article> Articles  
  109.     {  
  110.         get  
  111.         {  
  112.             return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Article>("PublishingCompanyModel.FK_Article_Author""Article");  
  113.         }  
  114.         set  
  115.         {  
  116.             if ((value != null))  
  117.             {  
  118.                 ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Article>("PublishingCompanyModel.FK_Article_Author""Article", value);  
  119.             }  
  120.         }  
  121.     }  
  122.   
  123.     /// <summary>  
  124.     /// No Metadata Documentation available.  
  125.     /// </summary>  
  126.     [XmlIgnoreAttribute()]  
  127.     [SoapIgnoreAttribute()]  
  128.     [DataMemberAttribute()]  
  129.     [EdmRelationshipNavigationPropertyAttribute("PublishingCompanyModel""FK_Payroll_Author""Payroll")]  
  130.     public EntityCollection<Payroll> Payrolls  
  131.     {  
  132.         get  
  133.         {  
  134.             return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Payroll>("PublishingCompanyModel.FK_Payroll_Author""Payroll");  
  135.         }  
  136.         set  
  137.         {  
  138.             if ((value != null))  
  139.             {  
  140.                 ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Payroll>("PublishingCompanyModel.FK_Payroll_Author""Payroll", value);  
  141.             }  
  142.         }  
  143.     }  
  144.     #endregion  
  145. }  
Each partial class is decorated with attributes. 
 
Let's take a look at these attributes. 
 
EdmEntityTypeAttribute
 
Attribute that indicates that the class represents an entity type. Without this attribute on top of the partial class, the class will not be recognised as an Entity Type.
 
GenWCF3.gif 
 
Example of using this attribute is shown below:
 
[EdmEntityTypeAttribute(NamespaceName="PublishingCompanyModel", Name="Author")]
 
Serializable
 
Indicates that a class can be serialized. Apply the SerializableAttribute attribute to a type to indicate that instances of this type can be serialized. The common language runtime throws SerializationException if any type in the graph of objects being serialized does not have the SerializableAttribute attribute applied.
Example is given below :
 
[Serializable()]
 
DataContractAttribute
 
Specifies that the type defines or implements a data contract and is serializable by a serializer, such as the DataContractSerializer. To make their type serializable, type authors must define a data contract for their type. 
 
Example is given below :
 
[DataContractAttribute(IsReference=true)]
 
Summary
 
In this part of this series, we saw how the data model and data entities are defined and created by the ADO.NET Data Entity Framework. Without understanding these internals, it is not possible to create a generic data access layer.