PetaPoco - Custom mapping with the Mapper interface
Monday, 4 April 2011
A couple of users have asked for better strict POCO support in PetaPoco. Specifically the ability to remap column and table names without decorating POCOs with attributes.
This post is about PetaPoco - "a tiny ORMish thing for your POCOs". Read more on the PetaPoco Project Page.
The easiest way to use PetaPoco is to decorate your POCOs with attributes that declare which properties should be mapped to which columns. Sometimes though, this isn't practical or some believe its too intrusive. So I've added a way to declare these bindings separately.
The PetaPoco.Database class now supports a static property called Mapper which acts a hook through which
you can install your own column and table info mappings.
First, you need to provide an implementation of PetaPoco.IMapper interface:
public interface IMapper
{
void GetTableInfo(Type t, ref string tableName, ref string primaryKey);
bool MapPropertyToColumn(PropertyInfo pi, ref string columnName, ref bool resultColumn);
}
When the GetTableInfo method is called, the tableName and primaryKey will be set to the default values
that PetaPoco has determined. Just change them if you want something else - remember to check the type first.
Similarly for the MapPropertyToColumn method - just change the values of the columnName and resultColumn
to suit your needs. Return true to allow the mapping, or false to ignore it.
Once you've implemented the IMapper, you just need to tell PetaPoco about it which is done through the static
Mapper property:
PetaPoco.Database.Mapper = new MyMapper();
Note there are a few limitations with all of this but I think the trade off for simplicity is worth it.
- The mapper is shared by all
Databaseinstances. PetaPoco caches these column mappings globally so it's not possible to provide different mappings for different database instances. - You can only install one mapper.
Available in github now, NuGet as soon as it back up.
1 Comment
Leave a comment
Really like PetaPoco so far, so refreshing. I have a question; do you have any plans to support nested POCOs where a POCO contains another POCO as a property? The convention could be that the name of the nested POCO property matches the name of a joined table in the query, or some kind of alias prefix in the query. This would really help when hydrating domain models where nested POCOS are used for structuring and object reuse. Otherwise my domain models would either have to be very flat or I'd have to write code to hydrate the domain entity from the POCO, both of which I'm reluctant to do
This is the kind of code I would love to see work with PetaPoco, the vat property would be automatically populated :
using System; using System.Collections.Generic; using System.Linq; using System.Text; using PetaPoco;
namespace PetaPocoTest { public class VAT { public string id {get; set;} public string description {get; set;} public double rate {get; set;} }
}