Take the 2-minute tour ×

I've been trying to revise the structural design of the C#.NET-based system I'm currently working on. Sorry, this came rather lengthy, but I cannot describe it shorter - it's a bit complex.

The system has two primary functions:

1)Retrieve rows from an SQL disk-based database, then serve them up using [DataContract]-marked objects via ASP to a web-based client, as well as receive UPDATEs to those and reroute them to the database.

2)Read off and serve the same kinds of objects to server-side / distributed modules which work with these, generate some result, and push it back to the database.

The results (some might ask: "why're you storing generated data?") of module computation do have to be stored in the database due to both size and length of computation required to obtain them, only to be retrieved in parts by the web-client through the (1) function.

Currently, all row-representing objects are defined as separate C# classes with a common trend but little to no inheritance, and no common base class. I want to completely break this pattern, and instigate more extensive inheritance based on a tree of abstract classes and possibly interfaces.

I've whipped up a "due-for-test" implementation in the past few days, but I'm concerned about the sanity of this design. Obviously, there is the object-relational impedance mismatch, which I deal with by only initializing the database-column-backed fields unless the other encapsulated objects are provided to the constructor. I'm not so concerned about that, and it's an issue for the old system design as well.

Here's what I have so far:

A DatabaseColumnAttribute class, which targets fields, and defines

  • name of the column where the data for the field resides.
  • database type (enum-backed locally) for this column. There's a fixed set of database types this system is designed to support, so be it.
  • whether or not the column is nullable.
  • read phrase(i.e. how do we represent this column in a SELECT query within an sql statement): this is generated automatically based on column type. There's a fixed number of types the data can be accessed in, so if there's a conversion involved when reading data from a column this will include it. Otherwise, just the column name.
  • write wrapper (i.e. database function that converts the data sent into the column from C# to the appropriate representation) - also generated based on column type.

All this is used within a DatabaseFieldColumnWrapper object, which contains all the methods required to transfer the data from the column to the field or vice-verse.

The DatabaseFieldColumnWrapper is constructed for each location in the code where a DatabaseColumnAttribute is used, meaning it's not quite "static", but rather class-based, since it modifies fields of derived classes. The fields can back properties, there's a BackedByFieldAttribute class as well, I'll skip it for brevity.

All of these are used within an abstract DataElement class, root of hierarchy. It defines the following abstract members: function that provides the backing-table's name for this class of objects, a read-only public Id property, a private function to set the Id (which corresponds to the primary key of the row in the table).

It also provides a protected static helper function to retrieve the DatabaseFieldColumnWrapper objects for specific fields based on Linq Expressions (to avoid "magic strings"). This can be used in derived types to easily synch the database representation for specific fields/columns.

It provides a Delete() method, which is (not a destructor, but a function) responsible for only deleting the database representation. The whole system is designed to allow asynchrony and multiple memory representations unless otherwise specified.

Here is the "less sane" part:

There is a DataElementAttribute class, which is designed to modify non-abstract derived types. It is not fully constructed completely right away where it's defined, instead filled-in in a thread-safe manner upon the construction of the first object of a derived type. It not inherited, and contains only data specific to the derived class required to speed up construction (i.e. construct all the necessary DatabaseFieldColumnWrapper objects before-hand and associate them with the fields).

This basically violates the C# OO model, since it's "static only with respect to current class in the hierarchy", not static to the whole chain. Basically, it makes the DataElmentAttribute object associate with a particular Type object. Each instance has a reference to it.

I don't know how to circumvent this issue, it seems to be best in terms of "code reuse", but it also seems like I'm violating a lot of things I shouldn't be when I do it. Any ideas, sugguestions?

share|improve this question

closed as off topic by Chris Lively, Ryan, Book Of Zeus, casperOne Feb 16 '12 at 23:02


You might do better with a more specific question rather than just "I think I'm doing something wrong." SO is specifically for Q&A type questions and this seems more like an extended discussion. –  cadrell0 Feb 15 '12 at 19:22
are you sure you can't leverage an existing c# orm like linq to sql or entity framwork, or even data sets, to form a sane design basis? –  Aaron Anodide Feb 15 '12 at 19:23
Okay, here's a more "question form"-type: how do I mimic class-based, although non-inherited (therefore not static), data [which I can use within the objects themselves] with C# OO model? I'm not looking for a "you don't" kind of answer here. –  Greg Kramida Feb 15 '12 at 19:26
Along with cadrell0's remark, this belongs on programmers.se –  Chris Lively Feb 15 '12 at 19:27
Alright, thanks, will try there. –  Greg Kramida Feb 15 '12 at 19:29