Model-First Design using ADO.NET Entity Framework 4.0


In this article we are going to see the second most impartment part of the ADO.NET entity framework 4.0. As the first part is traditional way of developing applications like, create Database schema and then creation of entity class follows. In this approach any changes to the schema after developing the conceptual entity classes needs to modified, even though it is quite simple to update the entity class from the schema, in case of big modifications, due to business change, it is time consuming process to synchronize the UX code and the entity class code.

In Model first approach, we will be creating the EDM, conceptual model, first with respect to the business, and keep evolute the EDM till it fits for the business and then generate the database schema based on the EDM. At least it makes easier to limit the huge changes. We will see the what limitations we have in this approach, everything comes with limitation.

We will be learning following

  1. Create Empty Model.
  2. EDM Designer.
  3. Creating Entities.
  4. Creating Associations and Relationships between Entities.
  5. Generating Schema SQL and Creating Database Schema.
  6. Performing CRUD Operations on Bands Entity
Create Empty Model

1. Create a solution called ModelFirstDesign.sln. I am using ASP.NET Web application template for this sample, VSTS 2010 Ultimate trail version.

EntityFramework1.gif

2. Add a new class library project to the solution and name it as ProjectTeam. As of now our primary focus is on creating entity class and the database for the same.

3. Add an ADO.NET Entity model item and name it as ProjectTeam.edm

EntityFramework2.gif

4. In the wizard select the Empty model and click on finish.

EntityFramework3.gif

EDM Designer

5. We will examine the empty mode and its tool box that helps us in creating the EDM entities, entity associations and Inheritance.
  • Entity: Allows you to design and create an Entity.
  • Association: Lets you create an association (or relationship) between two entities.
  • Inheritance: Lets you create an Inheritance relationship between two entities.

    EntityFramework4.gif
Creating Entities

6. Now we will create the entities in the model.
  1. Following are the entities we will be creating in the EDM.

    • ServiceLine: This is contains the service line details that a resource can belong to.
    • ProjectTeam: This entity will contain the individual team types. Like Dev, Test, DB and Support teams
    • ResourceDetails: This entity will contains the individual member details and which ServiceLine he/she belongs to and ProjectTeam
    • Brand: This entity tracks the resource brand.
     
  2. Creating individual entities. Drag an entity instance from the tool box. By default each entity should have an identity column to identity uniquely in the object cache. Try to learn about the ObjectStateManager, ObjectStateEntity and EntityState which is currently out of scope here.

  3. EntityFramework5.gif
     
  4. By selecting the Entity1 properties change the name of the Entity to ServiceLine
  5. EntityFramework6.gif
     

  6. By selecting the Id property change the name to ServiceLineID. Since this id we need as primary key make sure that the following properties set

  7. EntityFramework7.gif
     
  8. By right clicking on the Entity add the following scalar properties. Also repeat the same steps for all the Entities in the table given bellow. Make sure you are not creating the for now.

    EntityFramework8.gif

    ServiceLine Entity
     
  9. Column Name Data Type Description
    ServiceLineID Int32 Unique identifier
    SeviceLineName String The Service line name

    Band Entity

    Column Name Data Type Description
    BrandID Int32 Unique identifier
    BrandName String The brand name of the member

    ProjectTeam Entity

    Column Name Data Type Description
    TeamID Int32 Unique identifier
    TeamName String Name project team

    ResourceDetail Entity

    Column Name Data Type Description
    ResourceID Int32 Unique identifier
    FirstName String Resource First Name
    LastName String Resource Last Name
    MiddleName String Resource Middle Name
    Experience Int32 The resource experience

    So for your model should look like bellow

    EntityFramework9.gif

    Creating Associations and Relationships between Entities
     

  10. To create the relationship with between the table. Click on the Association in the tool box. Drag the ServiceLineID from ServiceLine to ResourceDetail entity and repeat the same for all of them.

    EntityFramework10.gif

    Generating Schema SQL and Creating Database Schema

    Before actually we create a Database Script from the model. We will need to create an empty database where we need to create our schema. Create a database called ProjectResource in the SQL Server 2008 (which I am using is EXPRESS edition)
  11.  
  12. Right click on the designer and choose 'Generate Database form Model'.

  13. EntityFramework11.gif
     
  14. Create a connection to the project that we created, and click next.

  15. EntFram12.gif
     
  16. In the next step the wizard created the DDL for the schema. Click on the finish button which will create a ProjectTeam.edmx.sql file to the project.

  17. EntFram13.gif
     
  18. Open the ProjectTeam.edmx.sql file examine. The file will have the following sections
     
    • Create all tables
    • Creating all primary key constraints
    • Creating all FOREIGN KEY constraints
  19. -- --------------------------------------------------

    -- Entity Designer DDL Script for SQL Server 2005, 2008, and Azure

    -- --------------------------------------------------

    -- Date Created: 07/16/2010 16:25:10

    -- Generated from EDMX file: D:\3. Research\EF4\ModelFirstDesign\ProjectTeam\ProjectTeam\ProjectTeam.edmx

    -- --------------------------------------------------

     

    SET QUOTED_IDENTIFIER OFF;

    GO

    USE [ProjectResource];

    GO

    IF SCHEMA_ID(N'dbo') IS NULL EXECUTE(N'CREATE SCHEMA [dbo]');

    GO

     

    -- --------------------------------------------------

    -- Dropping existing FOREIGN KEY constraints

    -- --------------------------------------------------

     

     

    -- --------------------------------------------------

    -- Dropping existing tables

    -- --------------------------------------------------

     

     

    -- --------------------------------------------------

    -- Creating all tables

    -- --------------------------------------------------

     

    -- Creating table 'ServiceLines'

    CREATE TABLE [dbo].[ServiceLines] (

        [ServiceLineId] int IDENTITY(1,1) NOT NULL,

        [ServiceLineName] nvarchar(max)  NOT NULL

    );

    GO

     

    -- Creating table 'ResourceDetails'

    CREATE TABLE [dbo].[ResourceDetails] (

        [ResourceId] int IDENTITY(1,1) NOT NULL,

        [FirestName] nvarchar(max)  NOT NULL,

        [LasteName] nvarchar(max)  NOT NULL,

        [Experience] int  NOT NULL,

        [MiddleName] nvarchar(max)  NOT NULL,

        [ServiceLine_ServiceLineId] int  NOT NULL,

        [ProjectTeam_TeamId] int  NOT NULL,

        [Band_BandId] int  NOT NULL

    );

    GO

     

    -- Creating table 'ProjectTeams'

    CREATE TABLE [dbo].[ProjectTeams] (

        [TeamId] int IDENTITY(1,1) NOT NULL,

        [TeamName] nvarchar(max)  NOT NULL

    );

    GO

     

    -- Creating table 'Bands'

    CREATE TABLE [dbo].[Bands] (

        [BandId] int IDENTITY(1,1) NOT NULL,

        [BandName] nvarchar(max)  NOT NULL

    );

    GO

     

    -- --------------------------------------------------

    -- Creating all PRIMARY KEY constraints

    -- --------------------------------------------------

     

    -- Creating primary key on [ServiceLineId] in table 'ServiceLines'

    ALTER TABLE [dbo].[ServiceLines]

    ADD CONSTRAINT [PK_ServiceLines]

        PRIMARY KEY CLUSTERED ([ServiceLineId] ASC);

    GO

     

    -- Creating primary key on [ResourceId] in table 'ResourceDetails'

    ALTER TABLE [dbo].[ResourceDetails]

    ADD CONSTRAINT [PK_ResourceDetails]

        PRIMARY KEY CLUSTERED ([ResourceId] ASC);

    GO

     

    -- Creating primary key on [TeamId] in table 'ProjectTeams'

    ALTER TABLE [dbo].[ProjectTeams]

    ADD CONSTRAINT [PK_ProjectTeams]

        PRIMARY KEY CLUSTERED ([TeamId] ASC);

    GO

     

    -- Creating primary key on [BandId] in table 'Bands'

    ALTER TABLE [dbo].[Bands]

    ADD CONSTRAINT [PK_Bands]

        PRIMARY KEY CLUSTERED ([BandId] ASC);

    GO

     

    -- --------------------------------------------------

    -- Creating all FOREIGN KEY constraints

    -- --------------------------------------------------

     

    -- Creating foreign key on [ServiceLine_ServiceLineId] in table 'ResourceDetails'

    ALTER TABLE [dbo].[ResourceDetails]

    ADD CONSTRAINT [FK_ServiceLineResourceDetail]

        FOREIGN KEY ([ServiceLine_ServiceLineId])

        REFERENCES [dbo].[ServiceLines]

            ([ServiceLineId])

        ON DELETE NO ACTION ON UPDATE NO ACTION;

     

    -- Creating non-clustered index for FOREIGN KEY 'FK_ServiceLineResourceDetail'

    CREATE INDEX [IX_FK_ServiceLineResourceDetail]

    ON [dbo].[ResourceDetails]

        ([ServiceLine_ServiceLineId]);

    GO

     

    -- Creating foreign key on [ProjectTeam_TeamId] in table 'ResourceDetails'

    ALTER TABLE [dbo].[ResourceDetails]

    ADD CONSTRAINT [FK_ProjectTeamResourceDetail]

        FOREIGN KEY ([ProjectTeam_TeamId])

        REFERENCES [dbo].[ProjectTeams]

            ([TeamId])

        ON DELETE NO ACTION ON UPDATE NO ACTION;

     

    -- Creating non-clustered index for FOREIGN KEY 'FK_ProjectTeamResourceDetail'

    CREATE INDEX [IX_FK_ProjectTeamResourceDetail]

    ON [dbo].[ResourceDetails]

        ([ProjectTeam_TeamId]);

    GO

     

    -- Creating foreign key on [Band_BandId] in table 'ResourceDetails'

    ALTER TABLE [dbo].[ResourceDetails]

    ADD CONSTRAINT [FK_BandResourceDetail]

        FOREIGN KEY ([Band_BandId])

        REFERENCES [dbo].[Bands]

            ([BandId])

        ON DELETE NO ACTION ON UPDATE NO ACTION;

     

    -- Creating non-clustered index for FOREIGN KEY 'FK_BandResourceDetail'

    CREATE INDEX [IX_FK_BandResourceDetail]

    ON [dbo].[ResourceDetails]

        ([Band_BandId]);

    GO
     

  20. Open the file and right click on the file and click on the Connection -> Connect, which will open the SQL Server "Connect to Database Engine "window and select the server instance and click on connect.

  21. EntFram14.gif
     
  22. Here we need to perform two steps. First verify the syntax and execute SQL
     
    • Right click on the opened file and select Validate SQL Syntax. Make sure that syntax validation successful.

    • EntFram15.gif
       
    • Now click on the Execute SQL.

      EntFram16.gif
       
    • Go back to your SQL Server database and verify the all tables are created.

      EntFram17.gif
       
    • One more thing that we have to confirm is that the relationships. Create a new database diagram and add all the tables to verify the same.

      EntFram18.gif
     
  23. By default EDM provides only Create Operation. Select Band entity, right click and select 'Table Mapping'notice that what is default.

    EntFram19.gif
Performing CRUD Operations on Bands Entity
  1. Create CreateBands, SelectBands, UpdateBands and DeleteBands Procedures in the Prject Resources DataBase.
     
    • CreateBands

       

      CREATE PROCEDURE CreateBands

             @BandName nvarchar(max)

      AS

      BEGIN

            

             BEGIN TRY

                    BEGIN TRANSACTION;

       

                           INSERT INTO ProjectResource.dbo.Bands

                           ( (

                           [BandName]

                           ) )

                           VALUES

                           (

                                 @BandName

                           ) ) ) ) )

                    COMMIT TRANSACTION;

             END TRY

             BEGIN CATCH

                    IF @@TRANCOUNT > 0

                           BEGIN

                           ROLLBACK TRANSACTION;

                    END

             END CATCH;

      END

      GO

       

    • SelectBands

      CREATE PROCEDURE [dbo].[SelectBand]

      AS

      BEGIN

             SELECT Bands.BandId, Bands.BandName

             FROM Bands

      END
      Go

    • UpdateBands

      CREATE PROCEDURE [dbo].[UpdateBands]

      @BandId int,

      @BandName nvarchar(max)

      AS

      BEGIN

      SET NOCOUNT ON;

       

             BEGIN TRY

                    BEGIN TRANSACTION;

       

                           UPDATE ProjectResource.dbo.Bands SET

                                 [BandName] = @BandName

                           WHERE [BandId] = @BandId

                    COMMIT TRANSACTION;

             END TRY

             BEGIN CATCH

                    IF @@TRANCOUNT > 0

                           BEGIN

                           ROLLBACK TRANSACTION;

                    END

             END CATCH;

      END
             GO

    • DeleteBands

      CREATE PROCEDURE DeleteBands

             @BandID int

      AS

      BEGIN

      BEGIN TRY

                    BEGIN TRANSACTION;

                           DELETE FROM ProjectResource.dbo.Bands

                           WHERE [BandId] = @BandId

                    COMMIT TRANSACTION;

             END TRY

             BEGIN CATCH

                    IF @@TRANCOUNT > 0

                           BEGIN

                           ROLLBACK TRANSACTION;

                    END

             END CATCH;

      END

      GO
       

  2. Go back to EDM and right click on the EDM and select Update Model from Database.

  3. EntFram20.gif
     
  4. Select the newly added stored procedures and click on finish. Go to Model bowers and expand the stored procedure node. You can see the procedures added there. Do you know? Adding SP to the EDM will not change anything to our Entities until we map them to the EDM functions!!

  5. EntFram21.gif
     
  6. Select the Band Entity in the EDM; select the Stored Procedure Mapping by right clicking on the Bands entity. Expand the <Select Insert Function> you can notice that the SP's are available for mapping.

  7. EntFram22.gif
     
  8. Now map the respective procedures to the Sp's. Make sure that DeleteBands BandId mapped to BandId under Property column.

  9. EntFram23.gif
     
  10. Notice that we don't have provision for mapping SelectBands procedure. For the same we need to create Import function. So that the SelectBands function will be available through a method for querying. To do the same, right click on the SelectBands procedure and click on Add Import Function.

  11. EntFram24.gif
     
  12. In the Add Import Function window set the values as follows and click on Ok. Notice that SelectBands function added under Import Function.

  13. EntFram25.gif
     
  14. Compile the Solution.
  15.  
  16. Now we will query the EDM for Bands. I have inserted some sample data from the backend.
  17.  
  18. Add the following code to query the EDM. You can download the source code.

    Since we have created our EDM with name ProjectTeam, EDM created a class ProjectTeamContainer that derives for ObjectContext. So our context becomes ProjectTeamContainer. The Import function that we have add to our solution, SelectBands, is called from the context.

  19. private void LoadBands()
            {
                var context = new ProjectTeamContainer();
                var bands = context.SelectBands();
                gvBandDetails.DataSource = bands;
                gvBandDetails.DataBind();
            }
     
  20. Add the following code to insert new Band.

  21. var context = new ProjectTeamContainer();
           context.AddToBands(
                  new Band()
                  {
                         BandName = "Some Band"
                  }
                  );

                  context.SaveChanges();
     

  22. Add the following code to delete the Band.

  23. var context = new ProjectTeamContainer();
           var band = (from mybands in context.SelectBands()
                  where mybands.BandId == selectedBandId
                  select mybands).First();
                  context.Bands.DeleteObject(band);
                  context.SaveChanges();
     
  24. Add the following code to update the bands.

  25. var context = new ProjectTeamContainer();
           var band = (from mybands in context.SelectBands()
                  where mybands.BandId == selectedBandId
                  select mybands).First();
                  band.BandName = txtBandName.Text;

    context.SaveChanges();

Now you can try with the other entities.

Thanks,

Chinna Srihari