Skip to content
troyji edited this page Aug 14, 2011 · 11 revisions

About

Introduction

This project is a fork of PetaPoco, a micro-ORM for .Net targeting a variety of databases through POCOs. The goal of a micro-ORM is to provide a database helper for data layers in a simplified, light-weight, and efficient way. They are not, however, meant to be a full blown, fully featured ORM such as Microsoft Entity Framework and nHibernate. Here is a quick taste of how quickly you can work with a database using PetaPoco.

Database db = new Database("MyConnectionString");
List<MyModel> records = db.Fetch<MyModel>("WHERE ColA=@0", colValue);

With this fork, I intend to add functionality for any commonly needed functionality that I feel is missing from the main project, as well as any useful improvements that I see can be made. Please be my guest and propose any such additions in the issues section. Do note, however, that I intend to maintain the spirit of a micro-ORM when selecting features.

Differences from the main project

Fluid Syntax (DbSql)

I have created an extension module (DbSql.cs) that adds a more fluid syntax in addition to the standard syntax. Basically, it allows you to start building Sql objects (DbSql objects) directly from a Database object, and allows you to execute them (Query, Fetch, ExecuteScaler, etc) directly. I may make this the default syntax in the future and move the current syntax to an extension module for backwards compatibility (TBD).

Standard syntax:

db.Fetch<MyModel>(Sql.Builder.Select("ColA", "ColB").From("TableA").Where("Id=@0", Id));

New fluid syntax:

db.Select("ColA", "ColB").From("TableA").Where("Id=@0", Id).Fetch<MyModel>();

Composite Primary Keys

I have come up with a new implementation for composite primary keys. It works by taking in a params list of keys in the PrimaryKeyAttribute instead of a single key. This implementation reserves backwards compatibility.

[PrimaryKey("ID1", "ID2")]

When using this multiple key feature, the sequence and auto-increment properties are invalid. Now we can use PetaPoco with composite key tables just as we would with single key tables.

Future Plans

Documentation

The documentation for PetaPoco consists of a series of examples and a collection of blog posts. I would like to see something a little more formal and better organized.

Non-Poco Queries

One feature that is missing from PetaPoco is the ability to select multiple values or partial records without using a POCO. It does support ExecuteScalar, but that only allows for selecting a single value. It also supports mapping to a Dynamic object, but that requires .Net 4.0. The idea is to allow mapping to built-in System.Data types instead.

DataTable Example:

List<DataTable> records = db.Fetch<DataTable>(Sql.Builder.Select("ColA", "ColB").From("TableA"));

DataRow Example:

List<DataRow> record = db.Single<DataRow>(Sql.Builder.Select("ColA", "ColB").From("TableA").Where("Id=@0", Id));

Insert / Update Value

I would like to have the ability to override a POCO instance's value during an insert and/or update. For instance, you may want to provide an initial value for a column using a database function during inserts (e.g. insert into a date column using the database's current date value). One option would be to allow this to be defined through model attributes. Another is to allow it to be defined at or near the query call (maybe a method call on a Sql object to define the replacement).

Multi-Poco Improvements

PetaPoco has multi-poco support for making queries with nested POCOs(POCOs that reference instances of other POCOs). To do this, it requires that each POCO be referenced in the template of the query (e.g. Query<PocoA, PocoB, PocoA>(...)). Furthermore, if you want one-to-many or man-to-one functionality, you have to supply part of the code yourself. Between existing PetaPoco attributes and primary key definitions, it should be possible to support all of this without having to explicitly declare all of the POCOs in the tree, write custom code, or even supply a full SQL query by simply adding a new ForeignKeyAttribute.

One-To-Many Example:

[PrimaryKey('Id')]
class TableA
{
    int Id;
    ...
    //'TableBId' is a column in 'TableA' referencing 'TableB''s Id column
    [ForeignKey("TableBId", Mapping.OneToMany)]
    List<TableB> Children;
}

[PrimaryKey('Id')]
class TableB
{
    int Id;
    ...
}

...
List<TableA> records = db.Query<TableA>(whereClause);

For Many-To-One, replace TableA with:

class TableA
{
    int Id;
    ...
    [ForeignKey("TableBId", Mapping.ManyToOne)]
    TableB Child;
}

For One-To-One, replace TableA with:

class TableA
{
    int Id;
    ...
    [ForeignKey("TableBId", Mapping.OneToOne)]
    TableB Child;
}