Blogs
Archive
  • November 2017 (1)
  • October 2017 (3)
  • September 2017 (4)
  • August 2017 (3)
  • July 2017 (3)
  • June 2017 (3)
  • May 2017 (1)
  • February 2015 (2)
  • January 2015 (1)
  • December 2014 (3)
  • February 2014 (2)
Tags View All Blogs
Scrum.NetMicrosoftVisual StudioVC++C#JavaTestingQuality AssuranceUX DesignSPAAngularKnockoutBackboneUnderscoreDatabaseMySQLBlockchainHyperledgerChaincodeEnterprise MobilityUIIonicCordovaHybrid AppCode ReviewTypescriptAndroidIOTReactICOVenture CapitalArtificial IntelligenceKotlinIoTFuchsia OSVirtual RealityVOIPCrowdfunding

Extending Behavior of Entities Generated by Entity Framework

As we all know the beauty of Entity Framework (EF) is that it automatically generates Classes for various model entities (tables, views etc.). No extra effort is needed to simulate the behavior of these entities by creating custom classes in solution (C# code) as we used to do before the introduction of EF.

Although we have all C# classes available in the solution for each of the entities in the database but still sometimes situation occurs where we need to have some additional members or properties in these auto generated classes but not at the cost of creating new columns to the tables in the database. It means having virtual properties for application scope only & there is no physical existence of these properties. So we can have following approaches for the:

  • Create new poco classes with the duplicating original properties and adding new properties
  • Extending the existing auto generated classes by EF

Again creating new C# classes is overhead of maintaining multiple classes for a single entity. It may lead to complexity and reduces the readability of the code as well. So extending the existing auto generated classes seems to be a good alternative.

Summary of Application: Trip Management is to keep track of various trips planned in an organization for their employees. 'EmpTripAssoc' table is to keep track of employees which are associated with any trip. So both EmpId and TripId are foreign keys here. Employee & Trip are lookup tables for employee's data and trips planned in the system. Below is the Entity Framework structure:

Trip Management Entity Framework structure

In this example an administrator would need to have an interface (TripPlan.aspx) where he can select multiple Employees from a list to associate them with a Trip. Let us say on the interface there one dropdown for Trip selection and grid below it for multiple employee selection & then a 'Save' button to save the association in 'EmpTripAssoc' table. Similarly on the same interface, grid would display employees in selected mode which are already planned for selected trip.

Find below the code written for Trip Plan page.

TripPlan.aspx
<%@ Page Language='C#' AutoEventWireup='true'CodeBehind='TripPlan.aspx.cs' Inherits='Use_of_Partial_Class.TripPlan' %>
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head runat='server'>
   <title> </title>
</head>
<body>
   <form id='form1' runat='server'>
   <div>
   <asp:DropDownList ID='tripDropdownList' runat='server' Width='120' DataSource='<%#TripList%>'
              DataTextField='TripDesc' DataValueField='TripId' OnSelectedIndexChanged='tripDropdownList_SelectedIndexChanged' AutoPostBack='true' ></asp:DropDownList><
     <asp:Button ID='saveButton'Text='Save'runat='server' OnClick='saveButton_Click' />
      <br><br>
</asp:BoundColumn> <asp:BoundColumn HeaderText='Name' DataField='EmpName'' > <asp:CheckBox runat='server' Checked='<%# DataBinder.Eval(Container.DataItem, 'IsSelected') %>'/> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid> </div> </form> </body> </html> >>

TripPlan.aspx.cs

public partial class TripPlan : System.Web.UI.Page
{
     protected List<Employee> EmployeeList = new List<Employee>();
    protected List<Trip> TripList = new List<Trip>();
    private TripManagementEntities objectContext = new TripManagementEntities();

    protected void Page_Load(object sender, EventArgs e)
    {
       TripList = this.objectContext.Trips.ToList()
       EmployeeList = this.objectContext.Employees.ToList();

      if (!IsPostBack)
      {
        tripDropdownList.DataBind();
        employeeGrid.DataBind();
      }
    }

    protected void saveButton_Click(object sender, EventArgs e)
    {
// do save functionality 
    } 

     protected void tripDropdownList_SelectedIndexChanged(object sender, EventArgs e) 
    {
      int selectedTripId = int.Parse(tripDropdownList.SelectedValue);
       foreach (varemp in EmployeeList
      {
 if (emp.EmpTripAssocs.Where(et => et.TripId == selectedTripId).FirstOrDefault() != null)
           emp.IsSelected = true;}

      employeeGrid.DataBind();
    }
 

Note that highlighted section in light blue color in the above code snippet, Employee entity is expected to have property called 'IsSelected' but it is not a table column in the database. For the same I have extended the Employee class by adding a new member 'IsSelected'' to it. Since auto generated Employee class is a partial class & so we can define the same class again anywhere in the system. It is always recommended to define this class (with additional members only) in a file different from originally generated by E. It is because whenever you update your EF model, auto generated file will be overwritten, so your additional properties will not be lost



//------------------------------------------------------------------------------
// 
//   This code was generated from a template.
// 
//   Manual changes to this file may cause unexpected behavior in your application.
//   Manual changes to this file will be overwritten if the code isregenerated
//
//------------------------------------------------------------------------------
 
 namespace Use_of_Partial_Class.Model{
   using System;
   using System.Collections.Generic;

   public partial class Employee 
    {
     public Employee()
      {
         this.EmpTripAssocs = new HashSet();
      }
 
    public int EmpId { get; set; }
    public string EmpName { get; set; }
    public System.DateTime JoinDate { get; set; }

    public virtual ICollection EmpTripAssocs { get; set; }

    }
}
 //User define Employee class in separate cs (POCO.cs in this example) file
 namespace Use_of_Partial_Class.Model 
 {
 
 public partial class Employee
      {
         public bool IsSelected { get; set; }
      }
 }

Moreover if you are dealing with WCF Domain Services then just decorate your Property with [DataMember] attribute so that the same property would be shared to client side code as well.

public partial class Employee
        {
[DataMember] 
           public bool IsSelected { get; set; } 
        }

EF does not raise any exception while adding, editing or deleting the same entity in the database using Entity Framework Context. It only keeps track of the properties which are mapped to actual table columns.