Category Archives: Entity Framework

Entity Framework Code-First in a “semi-production” context

Lately I used Entity Framework Code First in a “semi-production” context, not in an application, but for managing Load Tests. The scenario was I had a Load Test, based on a unit test (not a web test) and I had to manage a pool of users so that a single user wasn’t used at the same time by 2 instances of the unit test. Because the Load Test ran in a multi-agent scenario, this had to be accessible by all the agents running the unit test, thus a Database approach.

Preparing the Database in SQL Server

Entity Framework Code First will create and manage the Database for you. But in this context, I will be accessing the Database through a connection string using a SQL user, because not all the machines running agents are in the same domain, so going through a trusted connection isn’t an option. The SQL user will have access to the Database for the Load Test, but won’t have access to the master Database.

The first thing you need to do is to create the Database, because using the EF connection string would result in an authorization error when creating the Database.

After creating the Database setup the SQL user so that it can connect to it, read, write and manage the schema.

The Entity Framework Model and Context

The very first thing you need to do is add the Entity Framework NuGet package to your solution, this can be done either by going through the NuGet package manager:

blog12

Or just by opening the package manager console and typing in Install-Package EntityFramework

blog13

After that, create your model and your context. For our scenario we just needed an object User that has a UserName key, a static password that’s not going to the Database, a boolean InUse and a DateTime timestamp ReleasedOn so that we can ask for users that have been released by the unit test for the longest time.

namespace EFCodeFirstStart.Model
{
    using System;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;

    public class User
    {
        [Key]
        public string UserName { get; set; }

        [NotMapped]
        public string Password { get { return "myStaticPassword"; } }

        public bool InUse { get; set; }

        public DateTime ReleasedOn { get; set; }
    }
}

The context is really simple (we’ll get back to it later on in the post). You need to inherit from DbContext and you are implementing the default constructor to call the DbContext constructor that takes a connection string name so that you can point to the Database previously created.

namespace EFCodeFirstStart.Model
{
    using System.Data.Entity;

    public class LoadTestDataContext : DbContext
    {
        public LoadTestDataContext() : base("name=EFConnectionString") { }

        public DbSet<User> Users { get; set; }
   }
}

Creating the Database from the Model – Code First approach

Make sure that the connection string that you’re using on the DbContext contructor is configured in the app.config or web.config of your application:

<connectionStrings>
  <add name="EFConnectionString" providerName="System.Data.SqlClient" connectionString="Server=localhost; Database=LoadTestData; User=efcodefirst; Password=mypwd1234" />
</connectionStrings>

The first step is enabling Code First migrations for your application, this must be done for every project type with the following command Enable-Migrations:

blog14

When this step is executed a new folder Migrations and a Configuration.cs file will be created. The Configuration.cs file is one of the points where control is given to the developer in the Code First approach.

namespace EFCodeFirstStart.Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<EFCodeFirstStart.Model.LoadTestDataContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(EFCodeFirstStart.Model.LoadTestDataContext context)
        {
            //  This method will be called after migrating to the latest version.

            //  You can use the DbSet<T>.AddOrUpdate() helper extension method 
            //  to avoid creating duplicate seed data. E.g.
            //
            //    context.People.AddOrUpdate(
            //      p => p.FullName,
            //      new Person { FullName = "Andrew Peters" },
            //      new Person { FullName = "Brice Lambson" },
            //      new Person { FullName = "Rowan Miller" }
            //    );
            //
        }
    }
}

You then need to add migrations every time we want to snapshot the Database schema, so let’s do one now and call it InitialSetup by running the command Add-Migration InitialSetup:

blog15

This will create another file on the Migrations folder with a timestamp followed by _InitialSetup (the name you gave to the Migration):

namespace EFCodeFirstStart.Migrations
{
    using System;
    using System.Data.Entity.Migrations;
    
    public partial class InitialSetup : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Users",
                c => new
                    {
                        UserName = c.String(nullable: false, maxLength: 128),
                        InUse = c.Boolean(nullable: false),
                        ReleasedOn = c.DateTime(nullable: false),
                    })
                .PrimaryKey(t => t.UserName);
            
        }
        
        public override void Down()
        {
            DropTable("dbo.Users");
        }
    }
}

In a normal application scenario we would be done, as Entity Framework will handle the Database updates on every run, extra commands are only needed if we need to revert or do other extra work on the migrations. However, because I had to run this from a LoadTest project, the Database update has to be done manually, by calling Update-Database on the package manager console

blog16

Where did the EDMX go?

If you’re like me, you do a lot of code generation based on the ADO.NET EDMX model. So far Code First looked really nice and I was liking it a lot, but without the EDMX I don’t have a good source for writing templates against.

The folks at the Entity Framework team created the ability to Save the EDMX file in the framework, so we just need to call that every time we are changing the model (calling Update-Database). This is done by overriding the OnModelCreating method:

namespace EFCodeFirstStart.Model
{
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Text;
    using System.Xml;

    public class LoadTestDataContext : DbContext
    {
        public LoadTestDataContext() : base("name=EFConnectionString") { }

        public DbSet<User> Users { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var provider = new DbProviderInfo("System.Data.SqlClient", "2008");
            var model = modelBuilder.Build(provider);

            var writer = new XmlTextWriter(@"D:\TmpEdmx\my.edmx", Encoding.UTF8);
            EdmxWriter.WriteEdmx(model, writer);
        }
    }
}

Code First thoughts

So far I liked using Code First, seemed smooth, flexible and lean, making model and schema change iterations a breeze. With the added support to generate the EDMX everything is in place to do code generation like we used to do with Model First approaches.

Extending EF 4.x DbContext Generator to support Hashcode and Equality comparers

Currently I’m trying to fix a bunch of errors on a deep cloning template for EF 4.1 dbContext generated objects. This is done on a live database model, that’s fairly complex. One of the issues I had was the algorithm reaching a relation that it wasn’t supposed to be cloned, but later on, founding another relation where the same set of entities was supposed to be cloned, so I was left with relationships with the original entities that should be updated to the new cloned ones.

To fix this I had to keep track of what’s being cloned, so that in the end, I can run a “fixup” pass and update anything that’s referencing original entities that ended up being cloned later on. I came up with 2 ways to do this, either extend the objects and keep track of cloning information on a per object basis, or just track everything with a set of dictionaries during the process. Because many people in the team also work with these objects, and we have a junior guy, I didn’t want to pollute the objects with stuff that’s not business related, so I went with the dictionary approach.

The goal of this post isn’t to explain in detail how the template works, instead I just explain how to extend it. It contains my own flavor of code generation template syntax, that wasn’t born with T4, but with codesmith generation tools, and there I picked up a lot of habits that I still retain.

For the objects to be “Dictionary Ready” I implemented IEquatable, overrode GetHashCode() and Equals(object obj).

1.Getting a list of all the Primary Key properties in the entity

A good rule of thumb in all generation templates is to isolate all the different things you will work with in lists. The current template already isolates 3 things:

  • propertiesWithDefaultValues
  • collectionNavigationProperties
  • complexProperties
var propertiesWithDefaultValues = entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity && p.DefaultValue != null);
var collectionNavigationProperties = entity.NavigationProperties.Where(np => np.DeclaringType == entity && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
var complexProperties = entity.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == entity);

However we need a 4th IEnumerable containing all the primary keys for the entity, so we need to extend the previous code with:

var keyProperties = entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity && ef.IsKey(p));
var propertiesWithDefaultValues = entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity && p.DefaultValue != null);
var collectionNavigationProperties = entity.NavigationProperties.Where(np => np.DeclaringType == entity && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
var complexProperties = entity.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == entity);

2.Implementing IEquatable on the class header

Next the class header needs to be slightly changed to implement the IEquatable interface, but still retain the base class option from EF.

I replaced:

<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#>

With:

<#=Accessibility.ForType(entity)#> <#=code.SpaceAfter(code.AbstractOption(entity))#>partial class <#=code.Escape(entity)#><# if(entity.BaseType == null) { #> : IEquatable<<#=code.Escape(entity)#>><# } else { #> : <#=code.Escape(entity.BaseType)#>, IEquatable<<#=code.Escape(entity)#>><# } #>

3. Implementing IEquatable on the class body

At the end of the class, insert the implementation of Equals(EntityName other):

    public bool Equals(<#=code.Escape(entity)#> other)
    {
        if(other == null) return false;
        var result = true;
<#
	foreach(EdmProperty key in keyProperties)
	{
#>
        if(<#=code.Escape(key)#> != other.<#=code.Escape(key)#>) result = false;
<#
	}
#>
        return result;
    }

4.Overriding GetHashCode() and Equals(object)

For the finishing part, I overrode GetHashCode and Equals, also at the end of the class, with:

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 17;
<#
	foreach(EdmProperty key in keyProperties)
	{
#>
            hash = hash * 23 + <#=code.Escape(key)#>.GetHashCode();
<#
	}
#>
            return hash;
        }
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as <#=code.Escape(entity)#>);
    }

The GetHashCode implementation is a bit specific as it requires support for multiple keys. It is pulled from Joshua Bloch’s Effective Java. It is translated to C# and explained very well by Jon Skeet on Stackoverflow.