Reputation: 4875
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
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#.
Upvotes: 1
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
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
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
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