Archive

Archive for April, 2011

EF Code First:Tips & Tricks

April 20, 2011 3 comments

In this post I am going to show you some small tips & tricks about EF Code First which are quite useful.

Pluralization: By default Entity Framework pluralizes the table name, so if I have a domain object called ‘Employee’ it will create a table ‘Employees’. In order to turn it off you have to remove the Pluralizing table name from the convention collection of the modelbuilder object.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}

which is by the way is in the following namespace.

using System.Data.Entity.ModelConfiguration.Conventions.Edm.Db;

And the DbSet declaration is like this.

public DbSet<Employee> Employee { get; set; }

Ignoring properties: Suppose you have a property in your domain model which is quite important from the domain perspective but is not stored in the database. For example below is an Employee domain entity which has a property ‘IsQualifiedForTask’ which is computational property and is not stored in the database.

public class Employee
{
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public bool IsQualifiedForTask { get; set; }
}

In order to tell Entity Framework to do not persist this property in the database you could use the ‘Ignore’ keyword in the employee configuration class

public class EmployeeConfiguration : EntityTypeConfiguration<Employee>
{
   public EmployeeConfiguration()
   {
      this.Ignore(x => x.IsQualifiedForTask);
   }
}

Restricting Length: Suppose you want to restrict the size of a string column you can use the ‘HasMaxLength’ setting like this.

public class FacultyConfiguration : EntityTypeConfiguration<Faculty>
{
    public FacultyConfiguration()
    {
        this.Property(x => x.AnnuaLeave).IsRequired();
        this.Property(x => x.FirstName).HasMaxLength(100);
    }
}

Max string size: If you have a string property in your domain object and you don’t specify a size, by default Entity Framework will creates a corresponding column of type nvarchar(4000). This works fine for most of the scenario but what if it’s like a notes or a details field where the string can be more than 4000 characters. For example below is an article class which has a content column like this.

public class Article
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
}

and in the configuration class I will map the ‘Content’ column to max size like this.

public class ArticleConfiguration : EntityTypeConfiguration<Article>
{
    public ArticleConfiguration()
    {
        this.Property(x => x.Content).HasColumnType("nvarchar(max)");
    }
}

That’s all folks, until next time enjoy playing around with Entity Framework Code First.

EF Code First: Table Per Type

April 11, 2011 2 comments

In this post I am going to show you another type of mapping inheritance relationship which is called Table Per Type and it is quite similar to the Table Per hierarchy from the last post. The only difference is that here all the inheritance types will have their own table rather than combining them into one table.

Let start with a class diagram and see what we are trying to map.

Student Faculty Class Diagram

Person.cs

public abstract class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }
}

Student.cs

public class Student : Person
{
    public int CreditScore { get; set; }
}

Faculty.cs

public class Faculty : Person
{
    public int AnnuaLeave { get; set; }
}

PersonConfiguration.cs

public class PersonConfiguration : EntityTypeConfiguration<Person>
{
   public PersonConfiguration()
   {
      this.Map<Student>(x => x.ToTable("Student"))
          .Map<Faculty>(x => x.ToTable("Faculty"));
   }
}

POCOContext.cs

public class POCOContext : DbContext
{
   public DbSet<Person> People { get; set; }
   public DbSet<Student> Student { get; set; }
   public DbSet<Faculty> Faculty { get; set; }

   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
      modelBuilder.Configurations.Add(new PersonConfiguration());
   }
}

as you can see we just specify in our configuration class that each of the entity maps to an individual table. And now when you create the database context you will see the following relationship between the Person,Student and Faculty tables.

Per Table per Type Database diagram

So you can see mapping inheritance in EF Code First is relatively simple but be careful when choosing one over the other. For example inheritance is great and it just works but when it comes to reporting it can lead to some complication, so think from that point of view as well.

EF Code First: Table Per Hierarchy

April 6, 2011 5 comments

Continuing with my previous blog post about Entity framework today I am going to show you how to use Table Per Hierarchy relationship with Code First Approach.

It’s again a very useful mapping scenario and can be used for filtering specific types of domain objects.I am going to use a very simple real life scenario like a Person table and with that we have 2 derived types Players and Coaches, I know this may not be the best example for this kind of scenario but for illustration purpose and keep the example as simple as possible.

Lets first start with a domain model where we want to conceptually map 2 derived entities to a base entity.

Player Coach Class Diagram

and the code for 3 classes are as following :-

public abstract class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }
}
public class Player : Person
{
    public int SportId { get; set; }
    public int NoOfGames { get; set; }
}
public class Coach : Person
{
    public DateTime ContractStartDate { get; set; }
    public DateTime ContractEndDate { get; set; }
}

and this is how we define the relationship in the configuration file.

public class PersonConfiguration : EntityTypeConfiguration<Person>
{
    public PersonConfiguration()
    {
        this.Map<Player>(x => x.Requires("PersonType").HasValue("P"))
            .Map<Coach>(x => x.Requires("PersonType").HasValue("C"));
    }
}

and now all we have to do is add the configuration class to the OnModelCreating method of our POCOContext class.

modelBuilder.Configurations.Add(new PersonConfiguration());

Lets write a unit test to make sure the database is getting created and the table are generated with the right column.

[TestMethod()]
public void Should_be_able_to_create_POCOContext_database()
{
    var target = new POCOContext();
    target.Database.Initialize(true);
}

and this is how our People table looks like.

People table structure

So far so good but the best part is the data is flat combined structure in the database but yet in our domain model it is hierarchical and we can treat even the saving or retrieval of data in terms of domain model and not like treating it a data structure and separating the two kinds of Person with just types.

Lets write some more code to see it in action, first we will try adding a new Player into the table.

[TestMethod()]
public void Should_be_able_add_a_player()
{
    var player = new Player
                 {
                    FirstName = "Joe",
                    LastName = "Blogg",
                    SportId = 1,
                    NoOfGames = 120,
                    DateOfBirth = new DateTime(1980, 12, 12)
                 };

    context.Person.Add(player);
    context.SaveChanges();

}

and lets add a coach as well.

[TestMethod()]
public void Should_be_able_add_a_coach()
{
    var coach = new Coach
                {
                    FirstName = "Joe",
                    LastName = "Blogg",
                    DateOfBirth = new DateTime(1960, 1, 2),
                    ContractStartDate = new DateTime(2009, 12, 1),
                    ContractEndDate = new DateTime(2012,12,1)
                };
    context.Person.Add(coach);
    context.SaveChanges();
}

As you can see it can’t be easier than this and the power of this feature is then you are retrieving records of either a player or a coach type.

[TestMethod()]
public void Should_be_able_to_get_Players()
{
    var players = from p in context.Person.OfType<Player>()
                select p;

    var result = players.ToList();
    Assert.AreEqual(1,result.Count);
}

By just using OfType on the Person Entity the EF is doing the filtering of records based on the type and it’s doing all hard work. Hope you guys find it quite handy and use it in your project.

Follow

Get every new post delivered to your Inbox.

Join 41 other followers