I’m alive! It’s just that SisoDb takes all my time

No I’m not dead I’m just putting in every free second I got on my project SisoDb – Simple-Structure-Oriented-Db >> a NoSql .Net implementation for Sql-Server (http://www.sisodb.com), hence my lack of covering Entity framework code first. There are several others doing this, e.g Scott Guthrie. If you don’t follow his tweets, start following. He publishes nice tips on links to articles about e.g. EF code first etc.

Back to SisoDb. I will start covering examples here at this blog or at the official blog (http://blog.sisodb.com)

Currently I’m targeting SQL 2008 R2 but there’s also a somewhat “unofficial” version that should work against SQL-Azure. I’m also about to try and get it to work against VistaDb (http://www.vistadb.net)

//Daniel

EF4 – Code first CTP4

Since I’m on vacation and spend all my time on SisoDb I will not cover the new release of CTP4 for Code first and Entity framework 4, but instead direct you to a fairly nice post with good external reference links. So, instead of writing something that already has been written, go to Scott Hanselman’s blog: http://www.hanselman.com/blog/SimpleCodeFirstWithEntityFramework4MagicUnicornFeatureCTP4.aspx

I like that Microsoft has made it simpler and I really like the way you now can define your model in OnModelCreating. You can of course hook in your more detailed mappings via modelBuilder.Configurations.Add(new FooMapping());

//Daniel

Dealing with Enumerations and Entity framework 4 – code first

UPDATE! There’s a June CTP with new support for enums!

If you have an entity with an enumeration and you wan’t to store it using Entity framework 4, Code-only, you might run into problem. The convention-based mapping is sufficent for generating the schema but you will run into problem when trying to create an objectset.

The solution that I will present here is kind of simple: Make a custom-type that you map as a complex-type using ComplexTypeConfiguration, then you implement implicit operator overloading to provide implicit-conversion between this custom-type and the enumeration.

The Entity

public class Tifi : ICamyinEntity
{
    public Guid Id { get; set; }

    public byte[] Version { get; set; }

    public TifiType Type { get; set; }

    public string Title { get; set; }

    public string Description { get; set; }

    public string Source { get; set; }
}

The Enumeration

public enum TifiTypes : int
{
    Undefined = 0,
    Blog = 1,
    Video = 2
}

The Custom-type

public class TifiType
{
    public int Value { get; private set; }

    private TifiType()
        : this(default(TifiTypes))
    {}

    public TifiType(int value)
    {
        Value = value;
    }

    public TifiType(TifiTypes type)
    {
        Value = (int)type;
    }

    public static implicit operator int(TifiType type)
    {
        return type.Value;
    }

    public static implicit operator TifiType(int value)
    {
        return new TifiType(value);
    }

    public static implicit operator TifiTypes(TifiType type)
    {
        return (TifiTypes)type.Value;
    }

    public static implicit operator TifiType(TifiTypes type)
    {
        return new TifiType(type);
    }
}

The Mappings

public class TifiTypeMapping : ComplexTypeConfiguration<TifiType>, ICamyinMapping
{
    public TifiTypeMapping()
    {
        Property(o => o.Value);
    }
}

public class TifiMapping : EntityConfiguration<Tifi>, ICamyinMapping
{
    public TifiMapping()
    {
        HasKey(o => o.Id);
        Property(o => o.Id)
            .StoreGeneratedPattern = StoreGeneratedPattern.Identity;

        Property(o => o.Version)
            .IsConcurrencyToken()
            .IsRequired()
            .HasStoreType("timestamp")
            .StoreGeneratedPattern = StoreGeneratedPattern.Computed;

        Property(o => o.Source)
            .HasMaxLength(200)
            .IsUnicode()
            .IsRequired();

        Property(o => o.Title)
            .HasMaxLength(100)
            .IsUnicode();

        Property(o => o.Description)
            .HasMaxLength(1000)
            .IsUnicode()
            .IsOptional();
    }
}

That’s it. You will now be able to assign enumeration values to an instance of Tifi and it’s member Type.

var tifi = new Tifi
{
    Title = "My first Tifi",
    Description = "This works",
    Source = "http://daniel.wertheim.se",
    Type = TifiTypes.Blog
};

//Daniel

Entity framework 4 – CTP3 – Code first vs Linq to Sql

I just started doing some architectural changes to my old code in my previous article for Entity framework 4 (EF4) and at the same time updating it to use the new CTP3 add-on as well as writing the same code for Linq to Sql (L2Sql). I didn’t find any incompatibilities when updating from CTP2 to CTP3 but I did find something annoying. The Entity framework team is aware of this bug and will try to resolve this issue in the future.

This article shows you a solution where you DON’T use a designer or wizard for designing your model, it focuses on “Code first” where the entities are designed manually in code, as pure POCOs.

1 – The design

The design of my solution for dealing with storage of entities, has the following main components: Mappings-resolver, Storage-provider and Unit-of-work. A part from these there’s an ObjectContext and an ObjectContextBuilder, which you don’t have to deal with explicitly, since they are consumed by the Storage-provider and the Unit-of-work. The interface definition of a Storage-provider and the Unit-o-work, looks like this:


Interface for Storage-provider & Unit-of-work

1.1 – Mappings-resolver

The Mappings-resolver is responsible for finding the types that are to be handled by the Storage-provider; in other words, it locates your entities which are provided to the ObjectContextBuilder so that it can register mapping-information for each found entity and later on pass this information on to each created ObjectContext. For L2Sql, the mappings are described using attributes in the entity itself and the mappings are contained in an AttributeMappingSource. For EF4, the mappings are described using the fluent-API of the EntityConfiguration<T> class (more examples of this in the code section below).


L2Sql – Mappings-resolver


EF4 – Mappings-resolver

Both L2Sql and EF4 has two different Mapping-resolver implementations. One that scans for types in a specified assembly, and one that scans for types in the assembly that contains the interface that is provided via generics. With the second approach, the types also need to implement this interface, hence it acts as a filter, indicating if a type should be included or not. No matter which mappings-resolver you choose, all types needs to be a non-abstract class.

1.1.1 – L2SqlMappingsResolver

The L2Sql implementation looks for types that are classes that isn’t abstract and that are decorated with the attribute: TableAttribute. Each found type is then registered with the MappingSource’s model.

1.1.2 – EFMappingsResolver

The EF implementation looks for types that are classes that: isn’t abstract; extends EntityConfiguration<T>;where the name ends with Mapping.

1.2 – Storage-provider

The Storage-provider is designed to be long lived whilst the Unit-of-work is designed to be short-lived. The Storage-provider is tied to a certain implementation like: EF4 or L2Sql. It’s main responsibility is to create new instances of Unit-of-works, which then is used to-do CRUD-operations against the data source specified in the connection string passed to the Storage-provider. If you are familiar with NHibernate, you can look at the storage-provider as the Session factory.

1.3 – Unit-of-work

The Unit-of-work is designed to be short lived. It wraps the ObjectContext and provides a common API independent of the actual implementation (EF4 or L2Sql). It implements IDisposable so that you can use it in conjunction with an using-block. You use it to perform inserts, updates and deletes as well as for querying your model. When performing insert, updates and deletes, you have to flush your changes. You can see the Flush-operation as a sort of commit. Note! It’s not using transactions. If you want to use database transactions, you can i.e use the TransactionScope, or extend the Storage-provider to have a member: CreateUnitOfWorkWithTransaction() : ITransactionalUnitOfWork; or something like that.

L2Sql & EF4, Storage-provider and Unit-of-work

1.4 – ObjectContextBuilder & ObjectContext

The ObjectContextBuilder is responsible for holding mappings (added by passing a mappings-resolver to RegisterMappings) and for creating new instances of ObjectContexts, which are injected to the UnitOfWork instances.

1.4.1 – L2SqlObjectContext

As of right now this class just extends the DataContext class. It’s there to bring some consistency in the namings of all the components involved in the L2Sql-implementation. It might get extended in the future, but for now, it’s only implemented to bring consistency, so that L2SqlObjectContextBuilder and L2SqlUnitOfWork can work with L2SqlObjectContext rather than DataContext.

1.4.2 – EfObjectContextBuilder & ObjectContext

The EF4-implementation of ObjectContextBuilder, it extends the allready existing ContextBuilder. Also note that the EF4 ObjectContextBuilder holds a couple of alternative ways to register mappings, but as long as you use the Storage-provider, you don’t have to care about these. But if you want to extend something or use the builder directly, these members are there to let you add mappings.


L2Sql & EF4 – ObjectContextBuilder & ObjectContext

2 – How to consume the lib

That was a very brief and abstract explanation of the parts involved, now lets take a look at how to consume the lib.

2.1 – L2Sql

Step 1 – Define the model & the mappings

The entity can be placed freely in your assembly and doesn’t have to be generated by the DBML-designer. The example we are dealing with a very simple Customer class. Although I can specify mappings with XML in L2Sql, I tend to like the attribute-decoration approach more easygoing and clear, since I don’t have to locate a certain xml-file for managing the mappings.

[Serializable]
[Table(Name = "Customers")]
public class Customer
{
    [Column(Name = "CustomerId", IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false, AutoSync = AutoSync.OnInsert)]
    public int Id { get; set; }

    [Column(IsVersion = true, IsDbGenerated = true, CanBeNull = false, AutoSync = AutoSync.Always)]
    public byte[] Version { get; set; }

    [Column(CanBeNull = true, DbType = "NVARCHAR(100)")]
    public string Firstname { get; set; }

    [Column(CanBeNull = true, DbType = "NVARCHAR(100)")]
    public string Lastname { get; set; }

    public string Name
    {
        get { return string.Format("{0} {1}", Firstname, Lastname).Trim(); }
    }
}

Nothing spectacular. I have chosen to have an Id-field that is set-up as an identity as well as a Version-field for concurrency detection.

Step 2 – Extract the mappings

The ObjectContextBuilder needs to know where the data source is as well as what mappings to be used, hence we need to provide a connection string as well as a MappingsResolver.

Alternative 1

var mappingsResolver = new L2SqlMappingsResolverByAssemblyScan(assemblyWithEntities);

In the code above, I have chosen to go with a resolver that extracts the mappings from an assembly that contains my Linq-entities and the attribute-mappings (the Customer).

If I would like to I could let all my entities implement a certain interface and use it to extract the entities. The resolver will then look at the assembly containing the interface, and will look for the classes that implements this interface. To use this solution, I just need to use another resolver:

Alternative 2

var mappingsResolver = new L2SqlMappingsResolverByInterfaceFilterType<IEntity>();
Step 3 – Create a Storage-provider

After having defined my mappings and selected a strategy for fetching them (Step 1 & 2), I can now create my long-lived Storage-provider. Just give it a valid connection string for a Ms-Sql database and the mappings-resolver.

var storageProvider = new L2SqlStorageProvider(connectionString, mappingsResolver);

The rest of the Steps are common between the L2Sql and EF4 implementation, so before proceeding with Step 4, lets look at the EF4-implementation of Step 1 – 3.

2.2 – EF4

Step 1 – Define the model & the mappings

With the EF4 solution, the class doesn’t contain the attributes, instead the mappings are configured in a separate class, using the fluent-API of the EntityConfiguration-class.

public interface IEntity
{
    int Id { get; set; }
    byte[] Version { get; set; }
}

[Serializable]
public class Customer
    : IEntity
{
    public int Id { get; set; }

    public byte[] Version { get; set; }

    public string Firstname { get; set; }

    public string Lastname { get; set; }

    public string Name
    {
        get { return string.Format("{0} {1}", Firstname, Lastname).Trim(); }
    }
}

I have chosen to let my entities implement a certain interface so that I can re-use some mappingconfiguration by having a base-class for my mappings (EntityMapping<T>)

[Serializable]
public class EntityMapping<T> : EntityConfiguration<EfCustomer>
    where T : IEntity
{
    protected EntityMapping()
    {
        HasKey(o => o.Id);
        Property(o => o.Id)
            .IsIdentity();
        Property(o => o.Version)
            .IsConcurrencyToken()
            .IsRequired()
            .HasStoreType("timestamp")
            .StoreGeneratedPattern = StoreGeneratedPattern.Computed;   
    }
}

[Serializable]
public class CustomerMapping
    : EntityMapping<EfCustomer>
{
    public CustomerMapping()
    {
        Property(o => o.Firstname)
            .HasMaxLength(100)
            .IsUnicode()
            .IsOptional();
        Property(o => o.Lastname)
            .HasMaxLength(100)
            .IsUnicode()
            .IsOptional();
    }
}
Step 2 – Extract the mappings

When dealing with the EF4-solution the types to be extracted by the MappingsResolver isn’t the entities but instead the Mapping-classes. This is done using one of two alternatives:

Alternative 1

var mappingsResolver = new EfMappingsResolverByAssemblyScan(assemblyWithEntities);

Alternative 2

var mappingsResolver = new EfMappingsResolverByInterfaceFilterType<IEntityMapping>();

In the Alternative 2 the IEntityMapping could be an empty interface definition that is implemented by the mapping-classes.

Step 3 – Create a Storage-provider

After having defined my mappings and selected a strategy for fetching them (Step 1 & 2), I can now create my long-lived Storage-provider. Just give it a valid connection string, a providername (System.Data.SqlClient used by the DbProviderFactory) and the mappings resolver.

var storageProvider = new EfStorageProvider(connectionString, providerName, mappingsResolver);

That’s it. Now we have gone through all the implementation-specific scenarios. The rest of the steps are common between the L2Sql and EF4 implementation.

2.3 – The Unit-of-work

So the steps up until now has been specific depending on the selected solution: L2Sql or EF4. How you consume the Unit-of-work isn’t solution specific, so from now on, there will only be one set off code examples.

Create the data source

When doing integration testing it’s very useful to be able to teardown and set-up a new database.

storageProvider.SetupDataStore();
Consume the Unit-of-work

Remember that the Unit-of-work is supposed to be short-lived. It contains the instance of the underlying DataContext and provides CRUD-operations.

Insert single

var customer = new Customer {Firstname = "Daniel", Lastname = "Wertheim"};

using(var unitOfWork = storageProvider.CreateUnitOfWork())
{
    unitOfWork.Insert(customer);
    unitOfWork.Flush();
}

Insert many

var customers = new List<Customer>
                    {
                        new Customer {Firstname = "C", Lastname = "1"},
                        new Customer {Firstname = "C", Lastname = "2"}
                    };

using(var unitOfWork = storageProvider.CreateUnitOfWork())
{
    unitOfWork.InsertMany(customers);
    unitOfWork.Flush();
}

Update
There’s no real Update method, the way to see it is that either an entity belongs to the context (unit-of-work) or it doesn’t. If it where created in another context then the one you are using for updating it, you have to attach it to the new context. Sort of “letting the context be aware of the existence of the entity“. For this I use AttachAsModified.

var customer = new Customer { Firstname = "Daniel", Lastname = "Wertheim" };
            
using (var unitOfWork = storageProvider.CreateUnitOfWork())
{
    unitOfWork.Insert(customer);
    unitOfWork.Flush();
}

using (var unitOfWork = storageProvider.CreateUnitOfWork())
{
    customer.Firstname = "Scott";

    unitOfWork.AttachAsModified(customer);
    unitOfWork.Flush();
}

Delete
Just as with Update, if I work with entities created/fetched by another context (unit-of-work) I need to attach them to the new context. Although, when deleting, I don’t need to know each individual change of the entity’s properties, hence AttachMany will do.

var customers = new List<Customer>
                    {
                        new Customer {Firstname = "C", Lastname = "1"},
                        new Customer {Firstname = "C", Lastname = "2"}
                    };
            
using(var unitOfWork = storageProvider.CreateUnitOfWork())
{
    unitOfWork.InsertMany(customers);
    unitOfWork.Flush();
}

using(var unitOfWork = storageProvider.CreateUnitOfWork())
{
    unitOfWork.AttachMany(customers);
    unitOfWork.DeleteMany(customers);
    unitOfWork.Flush();
}

Querying
For querying you just make use of the Query method, which returns an IQueryable. Hence you can write linq-expressions or use lambdas to query it.

var customers = unitOfWork.Query<Customer>().Where(c => c.Firstname == "Daniel").ToList()

3 – Wrap up

So this was kind of an simple introduction, but it gives you a starting point to elaborate from. If I will make a follow-up it will be about mappings. But until then, for EF4 you can read about my old writings about mappings (different model and different infrastructure code):

The L2Sql and EF4 implementations can be downloaded here. I have zipped the entire solution. The project you are interested in is “Pls.Core.Storage“.

//Daniel