I'm trying to decide on the best strategy for accessing the database. I understand that this is a generic question and there's no a single good answer, but I will provide some guidelines on what I'm looking for.
The last few years we have been using our own persistence framework, that although limited has served as well. However it needs some major improvements and I'm wondering if I should go that way or use one of the existing frameworks. The criteria that I'm looking for, in order of importance are:
Client code should work with clean objects, width no database knowledge. When using our custom framework the client code looks like:
SessionManager session = new SessionManager();
Order order = session.CreateEntity();
order.Date = DateTime.Now;
// Set other properties
OrderDetail detail = order.AddOrderDetail();
detail.Product = product;
// Other properties
// Commit all changes now
session.Commit();
Should as simple as possible and not "too flexible". We need a single way to do most things.
Should have good support for object-oriented programming. Should handle one-to-many and many-to-many relations, should handle inheritance, support for lazy loading.
Configuration is preferred to be XML based.
With my current knowledge I see these options:
Improve our current framework - Problem is that it needs a good deal of effort.
ADO.NET Entity Framework - Don't have a good understanding, but seems too complicated and has bad reviews.
LINQ to SQL - Does not have good handling of object-oriented practices.
nHibernate - Seems a good option, but some users report too many archaic errors.
SubSonic - From a short introduction, it seems too flexible. I do not want that.
What will you suggest?
EDIT:
Thank you Craig for the elaborate answer. I think it will help more if I give more details about our custom framework. I'm looking for something similar. This is how our custom framework works:
It is based on DataSets, so the first thing you do is configure the
DataSets and write queries you need there.
You create a XML configuration file that specifies how DataSet tables map to objects and also specify associations between them (support for all types of associations).
3.A custom tool parse the XML configuration and generate the necessary code.
4.Generated classes inherit from a common base class.
To be compatible with our framework the database must meet these criteria:
Each table should have a single column as primary key.
All tables must have a primary key of the same data type generated on the
client.
To handle inheritance only single table inheritance is supported. Also the XML file, almost always offers a single way to achieve something.
What we want to support now is:
Remove the dependency from DataSets. SQL code should be generated automatically but the framework should NOT generate the schema. I want to manually control the DB schema.
More robust support for inheritance hierarchies.
Optional integration with LINQ.
I hope it is clearer now what I'm looking for.
Improve our current framework - Problem is that it needs a good deal of effort
In your question, you have not given a reason why you should rewrite functionality which is available from so many other places. I would suggest that reinventing an ORM is not a good use of your time, unless you have unique needs for the ORM which you have not specified in your question.
ADO.NET Entity Framework
We are using the Entity Framework in the real world, production software. Complicated? No more so than most other ORMs as far as I can tell, which is to say, "fairly complicated." However, it is relatively new, and as such there is less community experience and documentation than something like NHibernate. So the lack of documentation may well make it seem more complicated.
The Entity Framework and NHibernate take distinctly different approaches to the problem of bridging the object-relational divide. I've written about that in a good bit more detail in this blog post. You should consider which approach makes the most sense to you.
There has been a great deal of commentary about the Entity Framework, both positive and negative. Some of it is well-founded, and some of the seems to come from people who are pushing other solutions. The well-founded criticisms include
Lack of POCO support. This is not an issue for some applications, it is an issue for others. POCO support will likely be added in a future release, but today, the best the Entity Framework can offer is IPOCO.
A monolithic mapping file. This hasn't been a big issue for us, since our metadata is not in constant flux.
However, some of the criticisms seem to me to miss the forest for the trees. That is, they talk about features other than the essential functionality of object relational mapping, which the Entity Framework has proven to us to do very well.
LINQ to SQL - Does not have good handling of object-oriented practices
I agree. I also don't like the SQL Server focus.
nHibernate - Seems a good option, but some users report too many archaic errors.
Well, the nice thing about NHibernate is that there is a very vibrant community around it, and when you do encounter those esoteric errors (and believe me, the Entity Framework also has its share of esoteric errors; it seems to come with the territory) you can often find solutions very easily. That said, I don't have a lot of personal experience with NHibernate beyond the evaluation we did which led to us choosing the Entity Framework, so I'm going to let other people with more direct experience comment on this.
SubSonic - From a short introduction, it seems too flexible. I do not want that.
SubSonic is, of course, much more than just an ORM, and SubSonic users have the option of choosing a different ORM implementation instead of using SubSonic's ActiveRecord. As a web application framework, I would consider it. However, its ORM feature is not its raison d'être, and I think it's reasonable to suspect that the ORM portion of SubSonic will get less attention than the dedicated ORM frameworks do.
LLBLGen make very good ORM tool which will do almost all of what you need.
iBATIS is my favourite because you get a better grain of control over the SQL
Developer Express Persistence Objects or XPO as it is most known. I use it for 3 years. It provides everything you need, except that it is commercial and you tie yourself with another (single company) for your development. Other than that, Developer Express is one of the best component and framework providers for the .NET platform.
An example of XPO code would be:
using (UnitOfWork uow = new UnitOfWork())
{
Order order = new Order(uow);
order.Date = DateTime.Now();
uow.CommitChanges();
}
I suggest taking a look at the ActiveRecord from Castle
I don't have production experience with it, I've just played around with their sample app. It seems really easy to work with, but I don't know it well enough to know if it fits all your requirements
Related
I’m new to F# but would like to start building an API with it.
I have previously built C# API’s. In those we layer the architecture between models (being in the controllers), the domain DTO’s in the services and finally in the data layer if there needs to be any persistence.
Between these layers we use Automapper to map the types up and down the layers keeping a clean separation, for example none of our domain objects can have anything null in them (we use a maybe/option) and cater for this in our mappings between the objects.
I have seen examples of building API’s with F# and lots of getting started, but no good examples on architecture. I have also seen people try to use Automapper with F# but it seems shoehorned in and you don't see anyone use it in any of the example tutorials on the net, at least that I have found.
I’m just wondering what people do. Do you use something like Automapper in F#, do you keep a separation between your models and domain DTO’s? do you care? Am I thinking of this in too much of an oop way?
The closest I have come to any help has been on https://fsharpforfunandprofit.com/posts/recipe-part3/
I’m wondering what people do. Do you keep a separation between your models and domain DTO?
It's not that common but we prefer to keep everything manual. We don't create DTOs.
If we want to transfer objects we serialize and deserialize manually without creating additional objects.
DTOs are often used as an aid to serialization, but then you have to do just as much work to write the object <-> DTO mapping and end up with slow, reflection-based, unoptimized serialization.
I'm working with Laravel 5 but I think this question can be applied beyond the scope of a single framework or language. The last few days I've been all about writting interfaces and implementations for repositories, and then binding services to the IoC and all that stuff. It feels extremely slow.
If I need a new method in my service, say, Store::getReviews() I must create the relationship in my entity model class (data source, in this case Eloquent) then I must declare the method in the repo interface to make it required for any other implementation, then I must write the actual method in the repo implementation, then I have to create another method on the service that calls on the repo to extract all reviews for the store... (intentional run-on sentence) It feels like too much.
Creating a new model now isn't as simple as extending a base model class anymore. There are so many files I have to write and keep track of. Sometimes I'll get confused as of to where exactly I should put something, or find halfway throught setting up a method that I'm in the wrong class. I also lost Eloquent's query building in the service. Everytime I need something that Eloquent has, I have to implement it in the repo and the service.
The idea behind this architecture is awesome but the actual implementation I am finding extremely tedious. Is there a better, faster way to do things? I feel I'm beeing too messy, even though I put common methods and stuff in abstract classes. There's just too much to write.
I've wrestled with all this stuff as I moved to Laravel 5. That's when I decided to change my approach (it was tough decision). During this process I've come to the following conclusions:
I've decided to drop Eloquent (and the Active Record pattern). I don't even use the query builder. I do use the DB fascade still, as it's handy for things like parameterized query binding, transactions, logging, etc. Developers should know SQL, and if they are required to know it, then why force another layer of abstraction on them (a layer that cannot replace SQL fully or efficiently). And remember, the bridge from the OOP world to the Relational Database world is never going to be pretty. Bear with me, keeping reading...
Because of #1, I switched to Lumen where Eloquent is turned off by default. It's fast, lean, and still does everything I needed and loved in Laravel.
Each query fits in one of two categories (I suppose this is a form of CQRS):
3.1. Repositories (commands): These deal with changing state (writes) and situations where you need to hydrate an object and apply some rules before changing state (sometimes you have to do some reads to make a write) (also sometimes you do bulk writes and hydration may not be efficient, so just create repository methods that do this too). So I have a folder called "Domain" (for Domain Driven Design) and inside are more folders each representing how I think of my business domain. With each entity I have a paired repository. An entity here is a class that is like what others may call a "model", it holds properties and has methods that help me keep the properties valid or do work on them that will be eventually persisted in the repository. The repository is a class with a bunch of methods that represent all the types of querying I need to do that relates to that entity (ie. $repo->save()). The methods may accept a few parameters (to allow for a bit of dynamic query action inside, but not too much) and inside you'll find the raw queries and some code to hydrate the entities. You'll find that repositories typically accept and/or return entities.
3.2. Queries (a.k.a. screens?): I have a folder called "Queries" where I have different classes of methods that inside have raw queries to perform display work. The classes kind of just help for grouping together things but aren't the same as Repositories (ie. they don't do hydrating, writes, return entities, etc.). The goal is to use these for reads and most display purposes.
Don't interface so unnecessarily. Interfaces are good for polymorphic situations where you need them. Situations where you know you will be switching between multiple implementations. They are unneeded extra work when you are working 1:1. Plus, it's easy to take a class and turn it into an interface later. You never want to over optimize prematurely.
Because of #4, you don't need lots of service providers. I think it would be overkill to have a service provider for all my repositories.
If the almost mythological time comes when you want to switch out database engines, then all you have to do is go to two places. The two places mentioned in #3 above. You replace the raw queries inside. This is good, since you have a list of all the persistence methods your app needs. You can tailor each raw query inside those methods to work with the new data-store in the unique way that data-store calls for. The method stays the same but the internal querying gets changed. It is important to remember that the work needed to change out a database will obviously grow as your app grows but the complexity in your app has to go somewhere. Each raw query represents complexity. But you've encapsulated these raw queries, so you've done the best to shield the rest of your app!
I'm successfully using this approach inspired by DDD concepts. Once you are utilizing the repository approach then there is little need to use Eloquent IMHO. And I find I'm not writing extra stuff (as you mention in your question), all while still keeping my app flexible for future changes. Here is another approach from a fellow Artisan (although I don't necessarily agree with using Doctrine ORM). Good Luck and Happy Coding!
Laravel's Eloquent is an Active Record, this technology demands a lot of processing. Domain entities are understood as plain objects, for that purpose try to utilizes Doctrime ORM. I built a facilitator for use Lumen and doctrine ORM follow the link.
https://github.com/davists/Lumen-Doctrine-DDD-Generator
*for acurated perfomance analisys there is cachegrind.
http://kcachegrind.sourceforge.net/html/Home.html
I'm reading Taylor Otwell's book in which he suggests using the repository pattern. I get the theory behind it. That it's easy to switch implementations and decouples your code. I get the code too. And it is very nice to be able to switch by App::bind() with some other implementation. But I've been thinking for the last two hours how I should approach things for a new CRM I'm building. Almost no code yet but it might end up big.
I would prefer to simply use eloquent models and collection injected through the controller. That should make everything testable if I'm not mistaken.. . Allowing for mocks and such.
Does the repository pattern maybe offer any benefits towards scalability? In cases when more servers or resources are needed..
And why would anybody want to replace the Eloquent ORM once committed to its use? I mean most projects need a relational database. If I would build a UserRepositoryInterface and an implementation DbUserReponsitory, I cannot see when I would ever need or want to switch that with something else. This would count for most entities in my project (order, company, product, ...). Maybe to use another ORM to replace Eloquent? But I don't see myself doing this for this project.
Or am I missing something? My main concern is to have code that is readable and easy to test. Haven't really been testing that well up to now :)
It does not necessarily mean that ignoring the Repository pattern will give you headaches on the long run, but it certainly makes re-factoring code much easier thus you can easily write Test repositories and bind them with your controllers to easily test your business logic.
So even if it is not likely that you will replace Eloquent or any other part, encapsulating chunks of logic and operations in repositories will still be beneficial for you.
Dependency injection is nothing new in terms of design patterns, will it hurt your code, not necessarily. Will it hurt your ability to easily write / re-factor old code and swap it in easily... absolutely it will.
Design patterns exist as solutions to common problems. I would tell you straight away that ignoring the IoC container in Laravel and not dependency injecting will have a big impact on you later down the line if you're writing complex applications. Take for example that you may want different bindings based on request type, user role / group, or any other combination of factors, by swapping out the classes without impacting your calling code will be beyond invaluable to you.
My advice, do not ignore the IoC container at all.
As a sidenote, Service Providers are also your friend, I'd suggest you get well acquainted with them if you want to write great apps in Laravel 4.
I've recently 'discovered' Php-activerecord for use with CodeIgniter (using Sparks).
It is surely an easier way of building queries and getting data in and out of the database
than coding the models for yourself.
So my question is: is somebody using php-activerecord, instead of CodeIgniter's builtin activerecord, for a large project (ie. larger than the typical, tutorialish 'blog' example)?
What pitfals are there, when moving on from CodeIgniter models?
Thanks
ActiveRecord seems to be a well known pattern. In your particular case you should bare in mind, that you no longer need the CodeIgniter AR classes and methods.
Extending the php-activerecord models gives you many standarized methods dealing with your data. That's a good portion of code you would have to type in for yourself over and over again in each project (and beacause of the common CRUD actions, the code would be almost the same).
Great library!
I use it with my current CMS under development.
Once you get your head around relationships its a breeze. Activerecord\Model class is a joy to work with I find, however it would be nice to have a benchmarking wrapper. Really though if you have set your database architecture up right by indexing your foreign keys it should help.
Some nice features
callbacks
eager-loading
I have not personally used php-activerecord but it looks like a good ORM with good documentation. It looks like a nice time saver for larger projects, but for smaller ones i'd probably just stick with the standard activerecord class.
We are ready to start a brand new project at work, no legacy code. We did use Subsonic in the past and we pretty happy with it. But that was before Linq.
Has anyone had to face this same issue (Linq x Subsonic)?
What was your decision? What were the reasons?
Any insight appreciated.
SubSonic
Pros:
Nice and simple
Scaffolding
Cons:
Method signatures often accept string parms (though you're encouraged to use DAO string constants) which can be abused.
Keep in mind:
Requires Website project for no-code, hands-off model generation (needs the BuildProvider).
Linq To SQL
Pros:
Syntactic sugar in the IDE
MS supported
View the SQL to be executed in the IDE
Allows different levels of fiddling in the model, from auto-generation to explicit definitions down to object properties.
Cons:
Complex. You need to learn new concepts like the DataContext to be effective.
Keep in mind:
Some stackoverflow users question Linq to SQL's continued support.
Also evaluate the ADO.NET Entity Framework and here.
The one thing I love about LINQ, which I don't think SubSonic handles as gracefully, is automatically dealing with joins.
FROM a in db.Orders
where a.Total > 100
SELECT new {a.Item.Desc, a.Customer.Name};
will automatically generate SQL like thisL
select i.DESC, c.NAME
from ORDERS o
inner join ITEMS on o.ItemID = i.ItemID
inner join CUSTOMERS c on o.CustomerID = c.CUSTOMERID
where o.TOTAL > 100
What about NHibernate? Is it really out of the picture for new projects? Still, people coming from Java will find it familiar and you can also use it with .NET 2.0 and Mono.
I went with Linq because it's built into the framework. For those saying it will not be supported by Microsoft... it's LinqToSql that is going to be phased out. I believe one of the plans is to absorbe it into the Entity Framework.
I'm now using the Entity Framework. It also uses linq and basically it's exactly like linqToSql with more flexibility and power if you choose to use it.
I tend to avoid 3rd party frameworks and orms because eventually they die out as well. I believe they have more of a chance to die out because their life comes from how many people are interested in it and use it. Their life is also heavily dependent on it's main author/contributor.
My experience has been primary with SubSonic. It is very straight forward to deploy and you'll have your DAL completed in under a half hour. Bear in mind that this is a Swiss Army knife, as it is designed for utility. Basically you get a class generated per table, as well as the ability to peform lazy loading for collections. You can also execute stored procedures via the framework, so if you have complex data structures you can fetch them from the database and update a class that you hand craft.
I've used it on 5 major projects now, and am impressed with how quickly I became dependent on it.
I was in the same situation. LinQ is more "Visual", you do everything inside vstudio, and even Rob admits subsonic have a few things to match it.
IEnumerable, LINQDatasource ( with auto paging) and the visual modeling have convinced me to choose Linq over Subsonic.
The biggest risk with linq to sql is that Microsoft will grow tired of it and abandon it. There is a lot of speculation that this has already happened and that only the entity framework will be updated. Subsonic does not suffer from this and worse case you have the source code to make your edits.
You might want to look into what happens when MS stops developing LINQ to SQL,as it appears to be happening. SubSonics latest version is easier to create queries and more readable, then their previous version.