kmarks2
kmarks2

Reputation: 4875

ORM Architecture

Background: I have a project that is not at all large scale (2 ASP.NET web applications with like 10 pages each). These two web applications share a lot of back-end requirements, specifically the ability to manipulate a set of around 50 tables. They both hit the same RDBMS, which will always be MySQL.

Problem: A large feature-rich ORM library (Subsonic) was added to the project awhile back, which it turns out was just too much. It's too big, there's too many parts, there's too much overhead. Some Collections that are generated by Subsonic take >1min to create, whereas raw inline queries (bad I know) that accomplish the same take ~2s. It's not just Subsonic that is the problem, NHibernate and other ORM tools are just too big, with way too many features that will never be used. The scope of these projects will never get huge either. Also database agnosticism is unnecessary as we will never switch away from MySQL, and no one will ever use this tool except internally.

Clearly inlining queries is bad, unsafe, wrong. Linq is also not an option. Thus there is a need for some small custom ORM tool for me to package up in a library. My thought is to include:

Perhaps the pooled knowledge of StackOverflow can highlight shortcomings of this basic setup or offer improvements. Thanks in advance.

EDIT: One constraint (not sure how firm it is at this point) is that I not used a pre-built library. Higher ups are so turned off by Subsonic that any third party utility is likely to be rejected. So it's more of an architecture choice as opposed to a utility choice.

Upvotes: 3

Views: 1714

Answers (5)

Moises Barba
Moises Barba

Reputation: 11

You may want to take a look at Kerosene, here, or here.

Kerosene is a dynamic, self-adaptive and configuration-less easy-to-use ORM written in C#.

  • In its "basic" mode it represents a dynamic link with a given database, meaning you have full liberty to write any query or command against it, and retrieving the results in easy to use dynamic records.
  • In its "maps" mode, it provides a Entity Framework designed specifically to work with POCO objects, so that you don't have to modify your classes in any way, and just think in terms of objects instead of dealing with the database-related stuff.

Upvotes: 1

ChrisLively
ChrisLively

Reputation: 88074

The problem with your setup is that it simply doesn't address the issue at hand. Which, incidentally, is one of the problems with the majority of ORMs.

For example:

Let's say you have a Projects table and you need to get a list of projects whose status is Active. You don't need / want all of the fields, just the project name, status, date started and last update date.

How do you accomplish that in your layout? At the outset your table class won't work (requires connection and table name only) because it's going to require you to pull all of the columns: which is the problem you are already faced with.

Which means you have to use your Query method to get just what you want.. However, how does table know to only change the status column of a single row when you call .Save()? Now you are getting really complicated because it requires yet another custom query for this to be performant. Or, at the very least, you'll have to implement change tracking on each column and have your engine be smart enough to only update those values that have changed.

Now consider that the vast majority of your queries are like this. Meaning, you want to pull records that usually involve joins crossing table boundaries, you don't want all of the columns (for performance reasons), and your updates are going to be very targeted... This is where ORMs based on a direct mapping of your schema to classes will always fail the performance test.


So, what are you to do? My opinion is that you have to split the types of data access you are doing into two logical sets of operations. One set will involve having regulars OOP classes in order to perform validation and ensure that your business rules are properly functioning. These will be used when creating brand new records.

For the next set you can use simple DataTables or dynamic classes. Send your query to the database and pull back the records you want. Whenever doing an update, make sure that query is highly targeted. You can accomplish this with stored procs or inline sql; whichever you're more comfortable with. Dapper is actually quite good for this use case or just use Enterprise Library with regular SqlCommand/SqlConnections..

Point is, don't build your own 'ORM' unless you understand the problem with existing ones.

Upvotes: 2

AD.Net
AD.Net

Reputation: 13399

Why not try some microOrm like Dapper.Net (Stackoverflow orm btw). Micro-orms are pretty lightweight and performant. Although you'll have to be sure it'll work with mysql.

Upvotes: 2

tpeczek
tpeczek

Reputation: 24125

Before you start crafting your own tool you should check Micro ORM's, like for example:

And there is few others out there.

Upvotes: 6

Anton Gogolev
Anton Gogolev

Reputation: 115751

You really don't want to work with DataRow unless you're generating really custom queries. And you absolutely must not "sanitize" your queries: use parameters instead.

Try BLToolkit. In general, it's as simple as return db.SetCommand("SELECT * FROM Person").ExecuteList<Person>();

Upvotes: 4

Related Questions