Add Dapper to Enterprise Library?

.net dapper enterprise-library orm

Question

We are using the Enterprise Library as a standard DAL. Now, I would like to enjoy the benefits of Dapper. Looking at the implementation it is just extending the connection class.

Is it conceivable to set Dapper to extend Enterprise Library so we can enjoy both worlds? Or maybe someone already created this?

Accepted Answer

Yes, it is conceivable, and it works pretty well. We're using Dapper to supplement some older EntLib code, and simple queries are quick and painless. The biggest challenge was getting Transactions to work properly. You don't mention which version of EntLib you are using, but 4.0 and newer manage connections inside of TransactionScopes, so if you try to open another connection for Dapper inside of a scope with EntLib it will automatically escalate from a lightweight local transaction to DTC (Distributed Transaction Coordinator). EntLib doesn't really provide a way to grab the current open connection, so you have to derive from the Database class and expose the GetOpenConnection method.

public class EntLibDatabaseWrapper : Database
{
    // ...Constructor and overrides...

    public IDbConnection GetMyOpenConnection()
    {
        var connectionWrapper = GetOpenConnection();
        return connectionWrapper.Connection;
    }
}

Then use it something like this:

var db = DatabaseFactory.CreateDatabase();
var dbWrapper = new EntLibDatabaseWrapper(db.ConnectionString, db.DbProviderFactory);

using (var scope = new TransactionScope())
{
    var connection = dbWrapper.GetMyOpenConnection();

    try
    {
        var fooId = 
            connection.Query<int>("insert into Foo values (name = @name); select cast(scope_identity() as int", 
                                    new { name = "Foo" }).Single();
        var cmd =
            db.GetSqlStringCommand(
                "insert into Foo values (name = 'Bar'); select cast(scope_identity() as int)");
        var barId = int.Parse(db.ExecuteScalar(cmd));
        scope.Complete();
    }
    catch (Exception)
    {
        connection.Close();
        throw;
    }
}

If you have larger transaction scopes then you have to check to see if you are in an active transaction before you close each connection.

if(Transaction.Current == null)
     connection.Close();

Popular Answer

Why would you use Enterprise Library if you can use Dapper only? Instead of using DataSets and DataReaders, you can execute queries, which return strongly typed mapped objects.




Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why