Question

I’ve done some Googling but I have yet to find a solution, or even a definitive answer to my problem.

The problem is simple. I want to dynamically create a table per instance of a dynamically named/created object. Each table would then contain records that are specific to the object. I am aware that this is essentially an anti-pattern but these tables could theoretically become quite large so having all of the data in one table could lead to performance issues.

A more concrete example:

I have a base class/interface ACCOUNT which contains a collection of transactions. For each company that uses my software I create a new concrete version of the class, BOBS_SUB_SHOP_ACCOUNT or SAMS_GARAGE_ACCOUNT, etc. So the identifying value for the class is the class name, not a field within the class.

I am using C# and Fluent nHibernate.

So my questions are:

  1. Does this make sense or do I need to clarify more? (or am I trying to do something I REALLY shouldn’t?)
  2. Does this pattern have a name?
  3. Does nHibernate support this?
  4. Do you know of any documentation on the pattern I could read?

Edit: I thought about this a bit more and I realized that I don't REALLY need dynamic objects. All I need is a way to tie objects with some identifier to a table through NHibernate. For example:

//begin - just a brain dump
public class Account
{
  public virtual string AccountName { get; set; }
  public virtual IList Stuff { get; set; }
}

... somewhere else in code ...

//gets mapped to a table BobsGarageAccount (or something similar)
var BobsGarage = new Account{AccountName="BobsGarage"}; 
//gets mapped to a table StevesSubShop(or something similar)
var StevesSubShop = new Account{AccountName="StevesSubShop"};
//end

That should suffice for what i need, assuming NHibernate would allow it. I am trying to avoid a situation where one giant table would have the heck beat out of it if high volume occurred on the account tables. If all accounts were in one table... it could be ugly.

Thank you in advance.

Was it helpful?

Solution

Those classes seem awfully smelly to me, and attempt to solve what amounts to be an actual storage layer issue, not a domain issue. Sharding is the term that you are looking for, essentially.

If you are truly worried about performance of the db, and your loads will be so large, perhaps you might look at partitioning the table instead? Your domain objects could easily handle creating the partition key, and you don't have to do crazy voodoo with NHibernate. This will also more easily permit you to not do nutty domain level things in case you change your persistence mechanisms later. You can create collection filters in your maps, or map readonly objects to a view. The latter option would be a bit smelly in the domain though.

If you absolutely insist on doing some voodoo you might want to look at NHibernate.Shards, it was intended for easy database sharding. I can't say what the current dev state and compatibility is, but it's an option.

OTHER TIPS

Rather than creating a class on the fly, I would recommend a dynamic object. If you implement the right interfaces (one example is here, and in any case you can get there by inheriting from DynamicObject), you can write

dynamic bobsSubShopAccount = new DynamicAccount("BOBS_SUB_SHOP_ACCOUNT");
Console.WriteLine("Balance = {0}", bobsSubShopAccount.Balance);

in your client code. If you use the DLR to implement DynamicAccount, all these calls get intercepted at runtime and passed to your class at runtime. So, you could have the method

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
    if (DatabaseConnection.TryGetField(binder.Name, out result))
        return true;

    // Log the database failure here

    result = null;
    return false; // The attempt to get the member fails at runtime
}

to read the data from the database using the name of the member requested by client code.

I haven't used NHibernate, so I can't comment with any authority on how NHibernate will play with dynamic objects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top