Written on 4/18/2014 in Web development

010010000110010101101100011011000110111100100000​011101110110111101110010011011000110010000101100

I'll keep it short and sweet since it's nothing new. This chapter will be about the data layer of The Vorpal blog. Data is the game, Entity framework gets the fame. I'm saying this because while I was writing my entities I was sceptic. I worked with entity framework before and experienced some problems. Especially when using the references. After my logic was mostly written however, everything worked like I wanted it to. This small victory was due to the fact that I wasn't overthinking everything like I did with my previous experience with entity framework. I had the tendency of not believing in the power of the framework and was manually forcing and checking foreign key updates and filling up the references myself just because it wasn't loaded at first by my own mistake.

First steps

Right now, however, I probably didn't care enough, so I just put em out there, started testing what was working and what wasn't and got surprised. The writing of the data layer using entity framework probably took less time than the writing of this post did. And that's not that long either. I'll take the comment: 'well, your data layer is ridiculously simple', right now and deflect it. Stating that using previous technologies, even this simple data layer would take - I don't have an estimate - too long.

Entities

I started out writing a base class for my entities holding the Id and some auditing fields:

/// <summary>
/// A base entity that should be the base for every normal entity
/// </summary>
public class BaseEntity
{
    /// <summary>
    /// Primary key
    /// </summary>
    [Key]
    public int Id { get; set; }

    /// <summary>
    /// Entity last changed on
    /// </summary>
    public DateTime ChangedDate { get; set; }

    /// <summary>
    /// Entity was created on
    /// </summary>
    public DateTime AddedDate { get; set; }

    /// <summary>
    /// Entity is unused / inactive
    /// </summary>
    public bool Inactive { get; set; }
}

I currently only wrote the 3 entities I'll be using in the beginning. A Post entity that can have several tags and a topic. The Tag entity and the Topic entity. Everything is straightforward and easy to use. Although you have to keep your spider-sense up, I believe you can set this up very quickly, even for larger data sets. The amount of control offered by the code-first way is tremendous but it can also get frustrating. I was writing these entities quite fast and while they were also analysed beforehand, some stuff just wasn't working. My referenced Topic and the Tags weren't loading and the error messages I was getting at runtime were about as unclear as my spider-sense. After fiddling about a bit I noticed I made a rookie mistake and forgot the 'virtual' keyword. Without this keyword, entity framework couldn't override these fields and provide its own logic for when and how to fill them out. Anyhow, final entities are simple, like they should be in my opinion. See the KISS principle.

To make sure entity framework interprets the relationships correctly and mainly because the names it makes up / generates for the tables and column names are otherwise utterly ridiculous the next bit of code was added to the context:

/// <summary>
/// TheVorpalBlog entity framework code first Context
/// </summary>
public class VorpalContext : DbContext
{
    public VorpalContext()
        : base("DefaultConnection")
    {
        // Make sure the db isn't initalized automatically
        Database.SetInitializer<VorpalContext>(null);
    }

    public IDbSet<Post> Posts { get; set; } // IDbSets should be 'more' testable

    public IDbSet<Tag> Tags { get; set; }

    public IDbSet<Topic> Topics { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // Map many to many relationship between posts and tags (1 tag can have N posts, 1 post can have N tags)
        modelBuilder.Entity<Post>()
            .HasMany(m => m.Tags)
            .WithMany(m => m.Posts)
            .Map(m =>
                {
                    m.MapLeftKey("PostId");
                    m.MapRightKey("TagId");
                    m.ToTable("PostTags");
                }
            );

        // Map the relationship between post and topic (1 topic can have N posts) -> possibly redundant
        modelBuilder.Entity<Post>()
            .HasOptional<Topic>(m => m.Topic)
            .WithMany(m => m.Posts)
            .HasForeignKey(m => m.TopicId);
    }
}

When mapping a many to many relationship, like this one, the explicit mapping1 is required. Line number 27 - 29 tells Entity Framework to use these names when mapping the tables. This makes it easier to troubleshoot problems later. I'm already done with the data layer, next up: repositories!

Newer Older Top
blog comments powered by Disqus