In modern SQL Server versions (> 2008 IIRC) you can use User defined types. So your sproc can actually take an array of user types:
http://blogs.msdn.com/b/felixmar/archive/2010/10/27/how-to-create-and-execute-a-stored-procedure-using-a-table-as-a-parameter.aspx
In our app we actually use the repository pattern, but hack it a bit to get around slowness issues like you describe.
So, in your example, I'd do something like this:
using (CustomerBulkContext ctx = customerCollection.GetSaveContext())
{
foreach(Customer c in customerCollection)
{
if(c.ShouldSave())
{
c.Save(ctx);
}
}
ctx.Save();
}
The idea is that all the customers are added to an in-memory list inside the context, and then the actual commit to the DB is handled via the save context's .Save() method. That method then creates a list of SQL objects and hands them to a sproc that does the bulk update/insert/delete.
The problem with Object Oriented Programming is exactly that, the shape and vehicle examples. What I'm going to type below is not the actual truth, it is an opinion. An opinion shared by more people than just me though :)
Object oriented vs "Class oriented"
Your example where there would be a catalog and an episode is perfectly well. The problem is the functions you propose these Objects should get. That is where you go from Object Oriented Programming to Class Oriented Programming. Just fitting a lot of methods concerning the same concept in an Object doesn't make programming object oriented. All you do is make some sort of container for methods.
The Episode Object should be just an Object that "models" the Episode. It has a title, content, author, that kind of stuff. In no way should this Episode have access to the database. It is not supposed to save itself or be able to load more instances of other episodes. The same goes for Catalog, it should not be able to retrieve its newest Episode itself. A catalog is a model, it has a title and some other stuff.
Splitting up responsibilities
Getting stuff from and saving stuff to a DataBase is not a models responsibility. So someone else has to do the job. A good start might be to create a CatalogRepository which could look like so:
CatalogRepository
{
/**
* @param int $id
* @return Catalog
*/
public function getCatalogById($id)
{
//Do a query, populate a new Catalog and return it.
//The constructor of Catalog should not be the one quering!
//It should receive data, nothing more
}
/**
* @param Catalog $Catalog
*/
public function saveCatalog(Catalog $Catalog)
{
//stuff....
}
/**
* @param string $name
* @return Catalog[]
*/
public function searchCatalogsByName($name)
{
//do a full text search or something?
}
}
The Episode would have something along the same lines where you could get all Episodes for a specific Catalog but also the five most popular Episodes:
class EpisodeRepository
{
/**
* @param Catalog $Catalog
* @return Episode[]
*/
public function getEpisodesByCatalog(Catalog $Catalog)
{
}
/**
* @param int $amount
* @return Episode[]
*/
public function getMostPopularEpisodes($amount)
{
}
}
There are some really good guidelines for writing good object oriented code, take a look at SOLID for instance
Best Answer
Yes, let's say you have that database in the memory of your computer (in-memory-database) and let's say that the interface to it are variables in PHP.
Obviously an SQL query makes no sense here. First of all in PHP there is only one (and a half) way to create the object car and I'm sure you know that already:
Second SQL does not understand PHP directly. So using an SQL query would not make any sense.
Object orientation requires you to separate things. For example the object itself should not care about how (and when) it is stored into the memory, on disk, into an SQL database or printed out on paper to be typed in later again. If the car object would need to take care about all this, it would less be a car object but more the super-store-exchange-object called "car".
So just take care that one class is responsible for what it is good with:
And create new objects with new. You can find many hints how to make your code more simple and still improving it when writing OOP code in the post Don't be STUPID: GRASP SOLID! (Dec 2011; by NikiC).