views:

672

answers:

3

I'm in the process of writing a BSD licensed mini-ORM targeted at embedded databases (with support for ese, sqlite and sqlce out of the box)

After working lots with Rails in the last year I have been thinking of implementing an Active Record pattern in C#.

I have come up with some demo code and was wondering if the interface design is sound.

Here you go:

// first param is the class, second is the primary key
public class Order : ActiveRecord<Order,int> {
    BelongsTo<Customer> Customer { get; set; }

    [PrimaryKey(AutoIncrement=true)]
    public int Id { get; set; }

    public string Details { get; set; }
} 


[Index("FirstName", "LastName")]
[Index("LastName", "FirstName")] 
public class Customer : ActiveRecord<Customer,int> 
{

    public HasMany<Order> Orders { get; set; }

    [PrimaryKey(AutoIncrement=true)]
    public int Id { get; set; }

    [ColumnInfo(MinLength=4, MaxLength=255, Nullable=false)]
    public string FirstName { get; set; }

    [ColumnInfo(MinLength=4, MaxLength=255, Nullable=false)] 
    public string LastName { get; set; }

    public string Comments { get; set; }
}

[TestClass]
public class TestActiveRecord {

    public void Demo() 
    {
        var customer = Customer.Build();
        customer.FirstName = "bob";
        customer.LastName = "doe";

        var order = customer.Orders.Build();
        order.Details = "This is the first order"; 
        customer.Save();

        var customer2 = Customer.Find(customer.Id);

        Assert.AreEqual(1, customer2.Orders.Count); 
    }
 }

Sorry about this being a multiple questions in one question ... Can you think of any changes to this API? Are there any fatal flaws? Are there any open source ORMs that define similar interfaces?

+2  A: 

The Castle Active Record Project.

Although it's not a strict implementation of the Active Record pattern, it works very well. Bonus is you will get some experience with NHibernate in the process.

As someone who has written his own, very simple, OR/M only to find it lacking when scenarios got more complex, I would strongly urge you to take a hard look at Caste ActiveRecord and NHibernate, unless you are doing this as a learning experience.

RKitson
Will download and have a play, at first glance I think the way im proposing to do HasMany and BelongsTo is nicer ...
Sam Saffron
I also need to decide if I should require a ColumnInfo property on all db columns and if I really need an ActiveRecord property on the class (seems redundent)
Sam Saffron
Castle AR will not support ESE cause nhibernate will never support ESE, in an embedded scenario ESE has an overhead of only 80K for the redistribution which is amazing
Sam Saffron
I'm not a fan of any persistence framework that forces you to polute your inheritance heirachy.
RKitson
Any suggestion on how this can be done without polluting the hierarchy, whilst keeping the API simple?
Sam Saffron
Right on. Have fun. Didn't realize NHib didn't support ESE. I guess that means I'm gonna save a bunch of time with NHibernate, but will be limited to DBs that aren't ESE ;-)
RKitson
I had class level Attributes, [Persistable] I believe. I was using more of a repository pattern, so I didn't have any static data access methods on the class.
RKitson
In order to use Generics in the repositories I had all the [Persistable] classes also implement the IPersistable interface, which <T> had to implement.
RKitson
Now, one of the problems you are going to run into is the extra stuff you have to glom onto your classes for dirty checking.
RKitson
And are you going to support cascading? Or does the client need to keep track of which objects have changed, and the order that the saves/updates need to propagate to the DB?
RKitson
yerp building support for all cascading and will chuck in validations and lazy loading for good measure
Sam Saffron
Have fun. API looks fine, by the way.
RKitson
A: 

ActiveRecordMediator

Create a repository class that inherits from this AR class. Then you don't break your hierarchy and you implement a repository pattern along with your AR pattern!

A: 

Could someone possibly provide code to a very simple activerecord class that I could use to learn with? Looking at the source on projects like Castle and SubSonic is a bit overwhelming. I'd like to learn the active record pattern to get an idea of how it works. I know whatever I build would be nothing compared to Castle or SubSonic, but I think the learning experience would be great.

I looked at Hayden ActiveRecord, but I can't seem to find the source. Most of the active record related postings on his site are quite old.

Thanks.

Edit: Sorry, I should have created a new question for this...

Daniel